Giter Site home page Giter Site logo

studerw / td-ameritrade-client Goto Github PK

View Code? Open in Web Editor NEW
68.0 13.0 47.0 1.04 MB

TD Ameritrade Java Client

License: Apache License 2.0

Java 99.93% Shell 0.07%
tda ameritrade td-ameritrade-client stock-market stocks stock-trading stock-analyzer options option-trading forex

td-ameritrade-client's People

Contributors

bill-studer-itc avatar dependabot[bot] avatar gporter0205 avatar pauljulius avatar rjclancy avatar studerw avatar vphilipnyc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

td-ameritrade-client's Issues

Project example fetchQuote() invocation fails with UnrecognizedPropertyException "assetMainType"

The simple fetchQuote() example documented on the project's main page results in an UnrecognizedPropertyException for me …

Exception in thread "main" java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "assetMainType" (class com.studerw.tda.model.quote.EquityQuote), not marked as ignorable (39 known properties: "52WkLow", "highPrice", "marginable", "divAmount", "assetType", "bidPrice", "mark", "exchangeName", "regularMarketLastSize", "askPrice", "lastId", "securityStatus", "lastPrice", "lowPrice", "shortable", "symbol", "askSize", "bidSize", "openPrice", "delayed", "exchange", "volatility", "digits", "netChange", "closePrice", "tradeTimeInLong", "askId", "lastSize", "bidId", "regularMarketLastPrice", "description", "totalVolume", "quoteTimeInLong", "52WkHigh", "regularMarketNetChange", "peRatio", "regularMarketTradeTimeInLong", "divDate", "divYield"])
 at [Source: java.io.BufferedInputStream@6d025197; line: 1, column: 48] (through reference chain: java.util.LinkedHashMap["MSFT"]->com.studerw.tda.model.quote.EquityQuote["assetMainType"])
	at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:91)
	at com.studerw.tda.parse.TdaJsonParser.parseQuotes(TdaJsonParser.java:39)
	at com.studerw.tda.client.HttpTdaClient.fetchQuotes(HttpTdaClient.java:238)
	at com.studerw.tda.client.HttpTdaClient.fetchQuote(HttpTdaClient.java:246)

I'm new to the TD Ameritrade API, but am guessing assetMainType is a new JSON property and Jackson is not ignoring missing properties. Running the the Get Quote API manually results in …

{
  "MSFT": {
    "assetType": "EQUITY",
    "assetMainType": "EQUITY",
    "cusip": "594918104",
    "symbol": "MSFT",
…

... which indeed shows the assetMainType property in the response.

I'm surprised others haven't run into this, so am guessing I'm doing something incorrectly or overlooking something.

Thanks in advance!

"error": "invalid_grant"

Hi,

Please help me. I would like to use your API but I'm having trouble.

Followed this: https://developer.tdameritrade.com/content/simple-auth-local-apps

At this point: https://developer.tdameritrade.com/authentication/apis/post/token-0

The request looks like:

grant_type=authorization_code&refresh_token=&access_type=offline&code=MIbbl7ok....&client_id=OAXV....0XX&redirect_uri=http%3A%2F%2Flocalhost

but I get the response:

HTTP/1.1 400 Bad Request
.
.
{
"error": "invalid_grant"
}

Any idea why?

Following these detailed instructions. Seems very simple.

https://www.reddit.com/r/algotrading/comments/914q22/successful_access_to_td_ameritrade_api/

I'm so frustrated and any help is appreciated.

Thank you

Every API request generates a new access token

Hi,

Again, that you for spending the time to create this API. It's extremely useful.

In reviewing the code, to always set the Authorization header equal to "Bearer UNSET" in OauthInterceptor forces every request to fail and for a new access_token to be generated for every API call.

This is very inefficient as the access_token returned from the very first request has a time to live (TTL) value. It would be better and more efficient to cache the access_token and reuse it until it expires.

Thanks again

getUserPrincipals() is missing a "fields" paramater

Thanks for the java implementation.

Trying to get streaming quotes going with this and the main hurdle right now is that the getUserPrincipals() call is missing a fields argument
Per the guide at https://developer.tdameritrade.com/content/streaming-data#_Toc504640599 I'd need to provide streamerSubscriptionKeys,streamerConnectionInfo in the fields query param in order to get the keys and info for streaming.

Sidenote, I'd recommend making the following fields protected to allow for subclassing and extending of HttpTdaClient:

final TdaJsonParser tdaJsonParser = new TdaJsonParser();
final OkHttpClient httpClient;
private HttpUrl httpUrl;

Thanks again for this.

Exception question

I really like what you have done with this.

I've been running some option data retrievals for several months. Yesterday, I started getting an exception that I cannot understand. Can you take a look?

Here is the console output:
`08:26:28.555 [main] INFO com.studerw.tda.client.HttpTdaClient - Initiating HttpTdaClient...
08:26:28.903 [main] INFO com.studerw.tda.client.HttpTdaClient - get option chain for symbol: VXX
08:26:28.961 [main] INFO TDA_HTTP - REQUEST GET: https://api.tdameritrade.com/v1/marketdata/chains?symbol=VXX
08:26:28.961 [main] DEBUG TDA_HTTP - REQUEST Headers:
Accept: application/json
Authorization: Bearer UNSET

Exception in thread "main" java.lang.RuntimeException: java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_3, TLS_1_2], supportsTlsExtensions=true), ConnectionSpec()], supported protocols=[TLSv1]
at com.studerw.tda.client.HttpTdaClient.getOptionChain(HttpTdaClient.java:589)
at com.hpi.appcontrollers.TDAmeritradeFetchOptionsController.doPrices(TDAmeritradeFetchOptionsController.java:37)
at com.hpi.appcontrollers.CmdLineController.doCommandLine(CmdLineController.java:224)
at com.hpi.appcontrollers.AppController.startApp(AppController.java:62)
at com.hpi.appTPCcli.TPCcliEx.main(TPCcliEx.java:19)
Caused by: java.net.UnknownServiceException: Unable to find acceptable protocols. isFallback=false, modes=[ConnectionSpec(cipherSuites=[TLS_AES_128_GCM_SHA256, TLS_AES_256_GCM_SHA384, TLS_CHACHA20_POLY1305_SHA256, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_GCM_SHA256, TLS_RSA_WITH_AES_256_GCM_SHA384, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA], tlsVersions=[TLS_1_3, TLS_1_2], supportsTlsExtensions=true), ConnectionSpec()], supported protocols=[TLSv1]
at okhttp3.internal.connection.ConnectionSpecSelector.configureSecureSocket(ConnectionSpecSelector.kt:63)
at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.kt:345)
at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.kt:310)
at okhttp3.internal.connection.RealConnection.connect(RealConnection.kt:178)
at okhttp3.internal.connection.ExchangeFinder.findConnection(ExchangeFinder.kt:236)
at okhttp3.internal.connection.ExchangeFinder.findHealthyConnection(ExchangeFinder.kt:109)
at okhttp3.internal.connection.ExchangeFinder.find(ExchangeFinder.kt:77)
at okhttp3.internal.connection.Transmitter.newExchange$okhttp(Transmitter.kt:162)
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.kt:35)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.kt:82)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.kt:84)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.kt:71)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at com.studerw.tda.http.LoggingInterceptor.intercept(LoggingInterceptor.java:57)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at com.studerw.tda.client.OauthInterceptor.intercept(OauthInterceptor.java:46)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
at okhttp3.RealCall.execute(RealCall.kt:66)
at com.studerw.tda.client.HttpTdaClient.getOptionChain(HttpTdaClient.java:585)
... 4 more
`

Getting Error while creating Option order

Hi,
I am trying to create option order and I am getting following error

java.lang.RuntimeException: Non 200 response: [400 - {
"error" : "Following parameters are not allowed when placing an order: optionDeliverables"

Here is my code snippet
Order order = new Order();
order.setComplexOrderStrategyType(ComplexOrderStrategyType.NONE);
order.setOrderType(OrderType.LIMIT);
order.setSession(Session.NORMAL);
order.setOrderStrategyType(OrderStrategyType.SINGLE);
BigDecimal buyprice = new BigDecimal(1.0).setScale(2, RoundingMode.HALF_UP);
order.setPrice(buyprice);
order.setDuration(Duration.DAY);

  OrderLegCollection olc = new OrderLegCollection();
  olc.setInstruction(Instruction.BUY_TO_OPEN);
  olc.setQuantity(new BigDecimal("1"));
  order.getOrderLegCollection().add(olc);

  OptionInstrument instrument = new OptionInstrument();
  instrument.setSymbol("CCL_012122C30");
  instrument.setAssetType(AssetType.OPTION);
  olc.setInstrument(instrument);;

}

Any help for the same will be highly appreciated.

Introduce Lombok?

Hi William,

Would you be open to introducing Lombok as a dependency to the project? It would remove quite a bit of boilerplate code with your beans (classes under your "domain" folder).

I don't mind contributing a PR for this change - it would make things easier to read and less error-prone. I've used it on several projects (in prod too).

https://projectlombok.org

Thanks,
Victor

How to place an option order

Hi. I'm trying to place an option order. But, get errors from TD:
Non 200 response: [400 - {
"error" : "Following parameters are not allowed when placing an order: optionDeliverables"
}]
Here is how i submit an order. I do not set optionDeliverables. There is no setter for it.
Order order = new Order();
order.setOrderType(OrderType.LIMIT);
order.setSession(Session.NORMAL);
order.setDuration(Duration.DAY);
order.setPrice(new BigDecimal("1"));
order.setOrderStrategyType(OrderStrategyType.SINGLE);

    OrderLegCollection olc = new OrderLegCollection();
    order.getOrderLegCollection().add(olc);

    olc.setInstruction(OrderLegCollection.Instruction.BUY_TO_OPEN);
    olc.setOrderLegType(OrderLegCollection.OrderLegType.OPTION);
    olc.setQuantity(defaultOptionQuantity);

    OptionInstrument instrument = new OptionInstrument();
    instrument.setSymbol(symbol);
    instrument.setAssetType(Instrument.AssetType.OPTION);
    olc.setInstrument(instrument);

Java code giving error

I was using these API for automaticaly place orders. But today start getting following error.

java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.studerw.tda.model.account.RequestedDestination from String "C2": not one of the values accepted for Enum class: [NASDAQ, CBOE, C_2, ISE, NYSE, BATS, AMEX, PHLX, BOX, AUTO, INET, ECN_ARCA]
at [Source: (BufferedInputStream); line: 9265, column: 28] (through reference chain: java.util.ArrayList[235]->com.studerw.tda.model.account.Order["requestedDestination"])

Failed to get Auth token using current Refresh token

ref #9, #8
I am now experiencing this issue. Created new refresh token, checked on the tdAmeritrade site with joy.

Created a clean download with git (more than once), rebuilt, no joy. Using Java 1.8.

java.lang.IllegalStateException: Failed to get auth token using current refresh token
at com.studerw.tda.client.OauthInterceptor.intercept(OauthInterceptor.java:60)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:112)
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.kt:87)
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.kt:184)
at okhttp3.RealCall.execute(RealCall.kt:66)
at com.studerw.tda.client.HttpTdaClient.getOptionChain(HttpTdaClient.java:668)
at com.hpi.appcontrollers.TDAmeritradeFetchOptionsController.doPrices(TDAmeritradeFetchOptionsController.java:39)
at com.hpi.appcontrollers.CmdLineController.doCommandLine(CmdLineController.java:224)
at com.hpi.appcontrollers.AppController.startApp(AppController.java:61)
at com.hpi.appTPCcli.TPCcliEx.main(TPCcliEx.java:19)

New issue with retrieving transaction history

For me, Transaction API history is failing with the below error.

try { transactions = client.fetchTransactions(accountId, request); } catch (Exception e) { e.printStackTrace();}

LoggingInterceptor.intercept INFO - REQUEST GET: https://api.tdameritrade.com/v1/accounts/accountId/transactions?startDate=2021-01-30&endDate=2021-05-10
LoggingInterceptor.intercept INFO - RESPONSE [200 - OK]: https://api.tdameritrade.com/v1/accounts/accountId/transactions?startDate=2021-01-30&endDate=2021-05-10 in 488.0 ms
java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.studerw.tda.model.transaction.Transaction$AchStatus from String "Approved": not one of the values accepted for Enum class: [ERROR, CANCEL, REJECTED, APPROVED]
at [Source: (BufferedInputStream); line: 6696, column: 17] (through reference chain: java.util.ArrayList[206]->com.studerw.tda.model.transaction.Transaction["achStatus"])
at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:91)

Non 200 response

Hi there,

I got the response through https://api.tdameritrade.com/v1/oauth2/token successfully. I then copied the refresh token and client id (from app I created) into the properties as follows:

	Properties props = new Properties();
	props.setProperty("tda.client_id", "blah blah with @AMER.OAUTHAP at the end");
	props.setProperty("tda.token.refresh", "really long string");
	TdaClient tdaClient = new HttpTdaClient(props);

I keep getting this error for all API calls:

Exception in thread "main" java.lang.RuntimeException: Non 200 response: [404 - /v1/marketdata/FB/pricehistory] - https://apis.tdameritrade.com/v1/marketdata/FB/pricehistory
at com.studerw.tda.client.HttpTdaClient.checkResponse(HttpTdaClient.java:622)
at com.studerw.tda.client.HttpTdaClient.priceHistory(HttpTdaClient.java:165)
at com.tdameritrade.PlayGround.play1(PlayGround.java:54)
at com.tdameritrade.PlayGround.main(PlayGround.java:22)

Any ideas?

Thanks.

Theoretical Option Value returns the Mark

This isn't a bug in this codebase, but the TDA API seems to return the Mark, rather than the theoretical (Black-Scholes or otherwise) price. It's always halfway between the Bid/Ask.

It may make sense to either:
a) Comment out/Deprecate this property for now in the codebase with a comment about this bug
b) Use @JsonProperty("theoreticalOptionValue") on the mark property.

Probably makes sense to do a).

You can compare the value you get with TOS for proof.

fix javadoc

In file PriceHistReq, javadoc at top:
PriceHistReq request = PriceHistReqBuilder.priceHistReq()

believe it should be:
PriceHistReq request = PriceHistReq.Builder.priceHistReq()

Receiving unauthorized errors when calling API and 400 status when trying to get access token

I have the api client in a singleton in a websocket application that will handle multiple different clients. The flow will allow for people to create their own tda client with their keys and then call the api client. Below is my following issue specifically with the API.

When I try to get market history, I am getting 401 unauthorized and I cannot get my access token. I have tried with @AMER.OAUTHAP appended to the client id and without it, but to no avail. I have attached the flow for which you can draw the issue from. Is this an api issue? I see where the code is suppose to use my credentials to retrieve the token but I am not sure as to why It is not working nor do I see the appended tokens when a call is made as a param in the url.

tda_snip_1
tda_snip_2
tda_snip_3

error 404

I always receive a 404 error.
Example:
props.setProperty("tda.client_id", "...");
props.setProperty("tda.token.refresh","...")

    TdaClient tdaClient = new HttpTdaClient(props);
    
    Instrument resp = tdaClient.getBond("912810EG9");

RESULT:

[AWT-EventQueue-0] INFO com.studerw.tda.client.HttpTdaClient - Initiating HttpTdaClient...
[AWT-EventQueue-0] INFO com.studerw.tda.client.HttpTdaClient - Fetching Instrument with id: 912810EG9
[AWT-EventQueue-0] INFO TDA_HTTP - REQUEST GET: https://apis.tdameritrade.com/v1/instruments/912810EG9?fundamental=true
[AWT-EventQueue-0] INFO TDA_HTTP - RESPONSE [404 - /v1/instruments/912810EG9]: https://apis.tdameritrade.com/v1/instruments/912810EG9?fundamental=true in 1844.4 ms
Exception in thread "AWT-EventQueue-0" java.lang.RuntimeException: Non 200 response: [404 - /v1/instruments/912810EG9] - https://apis.tdameritrade.com/v1/instruments/912810EG9?fundamental=true
at com.studerw.tda.client.HttpTdaClient.checkResponse(HttpTdaClient.java:622)

Same for a request for quotes.
On the test website they bot work with 200.

BTW The request for quotes from your client has a different url:

GET /v1/marketdata/quotes?symbol=MSFT

while onn the official website is:

GET /v1/marketdata/MSFT/quotes?apikey=

Schwab API

Hi @studerw. Have you heard anything about the TDA API being migrated to Schwab? My accounts migrate over the weekend and I haven't seen anything other than superficial about it migrating "some day". Just curious if you had heard anything?

Thanks
Greg

Orders failed to parse.

Hi,

I'm using version 2.4.1 and when I tried to parse orders, I got following exception:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.studerw.tda.model.account.RequestedDestination` from String "C2": value not one of declared Enum instance names: [NASDAQ, CBOE, C_2, ISE, NYSE, BATS, AMEX, PHLX, BOX, AUTO, INET, ECN_ARCA]

Sample order

{
  "session" : "NORMAL",
  "duration" : "DAY",
  "orderType" : "LIMIT",
  "complexOrderStrategyType" : "NONE",
  "quantity" : 1.0,
  "filledQuantity" : 1.0,
  "remainingQuantity" : 0.0,
  "requestedDestination" : "C2",
  "destinationLinkName" : "AutoRoute",
  "price" : 0.64,
  "orderLegCollection" : [ {
    "orderLegType" : "OPTION",
    "legId" : 1,
    "instrument" : {
      "assetType" : "OPTION",
      "cusip" : "<HIDDEN>",
      "symbol" : "<HIDDEN>",
      "description" : "<HIDDEN>"
    },
    "instruction" : "SELL_TO_OPEN",
    "positionEffect" : "OPENING",
    "quantity" : 1.0
  } ],
  "orderStrategyType" : "SINGLE",
  "orderId" : <HIDDEN>,
  "cancelable" : false,
  "editable" : false,
  "status" : "FILLED",
  "enteredTime" : "<HIDDEN>",
  "closeTime" : "<HIDDEN>",
  "accountId" : <HIDDEN>,
  "orderActivityCollection" : [ {
    "activityType" : "EXECUTION",
    "executionType" : "FILL",
    "quantity" : 1.0,
    "orderRemainingQuantity" : 0.0,
    "executionLegs" : [ {
      "legId" : 1,
      "quantity" : 1.0,
      "mismarkedQuantity" : 0.0,
      "price" : 0.64,
      "time" : "<HIDDEN>"
    } ]
  } ]
}

Thank you.

Option Prices: repeated error on NAN instead of valid double

Not on every symbol but for example:
[main] INFO TDA_HTTP - RESPONSE [200 - OK]: https://api.tdameritrade.com/v1/marketdata/chains?symbol=AMZN in 236.1 ms [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - volatility using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - delta using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - gamma using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - theta using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - rho using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - theoreticalOptionValue using invalid NAN instead of a valid double [main] WARN com.studerw.tda.parse.BigDecimalNanDeserializer - volatility using invalid NAN instead of a valid double

Exception trying to load orders

Here's the code:

List orders = client.fetchOrders();

Below is the result. What could be causing this?

1011 [main] INFO TDA_HTTP - REQUEST GET: https://api.tdameritrade.com/v1/orders
1160 [main] INFO TDA_HTTP - RESPONSE [200 - ]: https://api.tdameritrade.com/v1/orders in 148.3 ms
Exception in thread "main" java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "executionType" (class com.studerw.tda.model.account.OrderActivityCollection), not marked as ignorable (one known property: "activityType"])
at [Source: java.io.BufferedInputStream@78691363; line: 33, column: 24] (through reference chain: java.util.ArrayList[0]->com.studerw.tda.model.account.Order["orderActivityCollection"]->java.util.ArrayList[0]->com.studerw.tda.model.account.OrderActivityCollection["executionType"])
at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:83)
at com.studerw.tda.parse.TdaJsonParser.parseOrders(TdaJsonParser.java:133)
at com.studerw.tda.client.HttpTdaClient.fetchOrders(HttpTdaClient.java:421)
at stocks.Trade.getOrders(Trade.java:72)
at stocks.Trade.main(Trade.java:35)
Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "executionType" (class com.studerw.tda.model.account.OrderActivityCollection), not marked as ignorable (one known property: "activityType"])
at [Source: java.io.BufferedInputStream@78691363; line: 33, column: 24] (through reference chain: java.util.ArrayList[0]->com.studerw.tda.model.account.Order["orderActivityCollection"]->java.util.ArrayList[0]->com.studerw.tda.model.account.OrderActivityCollection["executionType"])
at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:52)
at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:839)
at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:1045)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1352)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownVanilla(BeanDeserializerBase.java:1330)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:264)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:520)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:95)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:258)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:125)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:217)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:25)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3736)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2803)
at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:81)
... 4 more

RuntimeException: Empty json body: [200 - ] - https://api.tdameritrade.com/v1/marketdata/quotes?symbol=blahblah1

Hi,

Using:

<dependency>
   <groupId>com.studerw.tda</groupId>
   <artifactId>td-ameritrade-client</artifactId>
   <version>2.4.1</version>
</dependency>

TdaClient client = new HttpTdaClient();
ArrayList<String> symbols = new ArrayList<>();
symbols.add("blahblah1");
List<Quote> quotes = client.fetchQuotes(symbols);

causes:

Exception in thread "main" java.lang.RuntimeException: Empty json body:  [200 - ] - https://api.tdameritrade.com/v1/marketdata/quotes?symbol=blahblah1
	at com.studerw.tda.client.HttpTdaClient.checkResponse(HttpTdaClient.java:852)
	at com.studerw.tda.client.HttpTdaClient.fetchQuotes(HttpTdaClient.java:241)

The code should be able to handle a bad symbol without throwing a RuntimeException.

Thanks

Fetching Child Order Price

Hi All,
I have submitted Trigger order (One triggers other Buy and Sell). My Buy order has been filled but my sell order has not been filled. I want to fetch my triggered sell order but I am not getting it. Is there any API I can call for the same.

Generating a new access token with every API call

@studerw I'm not sure if this is the way it's supposed to work or if I'm doing something wrong in my implementation of the API, but every call I make generates a new access token. I actually got called out by the TDA API team for generating "excessive" access tokens on a daily basis. I'm working my way through all the documentation and debugging the code to figure out if I'm doing something wrong, but thought I would check with the source while doing that. Thanks Greg.
Screenshot 2022-01-03 113016

PlaceOrder question

Hi Its actually question.
I have used placeOrder and it went through successfully. But how do I know the order is placed. Does this api return order id or status ? or Do I need to run fetchorders to verify ?
or I can set my own orderid to placeorder so that I can fetch by orderid to verify the existence ?

Streaming API

Hi,

First of all, thanks for the package. It is simple to use and works great.

Can you add streaming API assuming TD supports streaming?

Streaming API allows

  • user to specify list of symbols and callback methods which can be called from another thread
    user can decide whether to use queue, messaging, etc. on callback
  • user can update the list of instruments, adding or removing to subscribed symbols
  • prefer to have real-time callback

Thanks for your consideration,
Brian

placeOrder

Great job on the api. Would it be possible to return the id of the newly created order after the call?

Thanks,
Vlad

Using Spring and getting javax.validation.NoProviderFoundException with PriceHistReq Validation

I've added spring-boot-starter-validation since I'm building a Spring Boot app, and tried hibernate-validator in a mix of combinations, clean, cleared-cached, used "@ Validated" annotation, and declared the Validation bean manually but I keep getting:
javax.validation.NoProviderFoundException: Unable to create a Configuration, because no Bean Validation provider could be found. Add a provider like Hibernate Validator (RI) to your classpath.

This is how I'm using the PriceHistReq, and where it throws:

        PriceHistReq req = PriceHistReq.Builder.priceHistReq()
                .withSymbol(symbol)
                .withPeriodType(PeriodType.valueOf(periodType))
                .withPeriod(period)
                .withFrequencyType(FrequencyType.valueOf(frequencyType))
                .withFrequency(frequency)
                .withStartDate(startDate)
                .withEndDate(endDate)
                .withExtendedHours(extendedHours)
                .build();
        HttpTdaClient tdaClient = new HttpTdaClient();
        PriceHistory priceHistory = tdaClient.priceHistory(req);

at javax.validation.Validation$GenericBootstrapImpl.configure(Validation.java:291) ~[validation-api-2.0.1.Final.jar:na]
at javax.validation.Validation.buildDefaultValidatorFactory(Validation.java:103) ~[validation-api-2.0.1.Final.jar:na]
at com.studerw.tda.model.history.PriceHistReqValidator.(PriceHistReqValidator.java:20) ~[td-ameritrade-client-2.4.1.jar:na]
at com.studerw.tda.client.HttpTdaClient.priceHistory(HttpTdaClient.java:188) ~[td-ameritrade-client-2.4.1.jar:na]

CancelTime response not parsed

Hello,

I feel this is a simple issue, but I'm a newbie in programming this stuff. Anyhow, I've got a GTC stop loss order and the response is not being parsed properly it appears.

Response and stack trace below, some response values changed to dummy values:

[ {
"session" : "NORMAL",
"duration" : "GOOD_TILL_CANCEL",
"orderType" : "STOP",
"cancelTime" : "2020-09-04",
"complexOrderStrategyType" : "NONE",
"quantity" : 50.0,
"filledQuantity" : 0.0,
"remainingQuantity" : 50.0,
"requestedDestination" : "AUTO",
"destinationLinkName" : "CDRG",
"stopPrice" : 172.0,
"orderLegCollection" : [ {
"orderLegType" : "EQUITY",
"legId" : 1,
"instrument" : {
"assetType" : "EQUITY",
"cusip" : "90138F102",
"symbol" : "TWLO"
},
"instruction" : "SELL",
"positionEffect" : "CLOSING",
"quantity" : 50.0
} ],
"orderStrategyType" : "SINGLE",
"orderId" : 123456789,
"cancelable" : true,
"editable" : true,
"status" : "WORKING",
"enteredTime" : "2020-05-08T17:00:37+0000",
"tag" : "WEB_GRID",
"accountId" : ABCDEFGHID
} ]

Exception in thread "main" java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of com.studerw.tda.model.account.CancelTime (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2020-09-04')
at [Source: (BufferedInputStream); line: 5, column: 18] (through reference chain: java.util.ArrayList[0]->com.studerw.tda.model.account.Order["cancelTime"])
at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:83)
at com.studerw.tda.parse.TdaJsonParser.parseOrders(TdaJsonParser.java:130)
at com.studerw.tda.client.HttpTdaClient.fetchOrders(HttpTdaClient.java:408)

Thanks.

Option Chain: Some tickers fail

Using 2.3.0

This is odd. I get the errors noted below but not on every ticker. DIS fails every time while the other 17 I'm after are fine every time. I cannot discover why DIS would be unique in this way.

I set all the properties, then call into an instance of HttpTdaClient as: httpTdaClient.getOptionChain("DIS").

The output notes that 'STOCK' is not part of an enum but I cannot find that enum. Also, most of the ones I'm after are stocks, e.g., aal, appl, amzn, docu, hd, jpm, etc.

[main] INFO TDA_HTTP - REQUEST GET: https://api.tdameritrade.com/v1/marketdata/chains?symbol=DIS [main] INFO TDA_HTTP - RESPONSE [200 - OK]: https://api.tdameritrade.com/v1/marketdata/chains?symbol=DIS in 214.5 ms Exception in thread "main" java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.studerw.tda.model.account.OptionDeliverable$AssetType from String "STOCK": not one of the values accepted for Enum class: [MUTUAL_FUND, CURRENCY, INDEX, FIXED_INCOME, OPTION, CASH_EQUIVALENT, EQUITY] at [Source: (BufferedInputStream); line: 1, column: 57843] (through reference chain: com.studerw.tda.model.option.OptionChain["callExpDateMap"]->java.util.LinkedHashMap["2021-01-15:9"]->java.util.LinkedHashMap["23.0"]->java.util.ArrayList[0]->com.studerw.tda.model.option.Option["optionDeliverablesList"]->java.util.ArrayList[1]->com.studerw.tda.model.account.OptionDeliverable["assetType"]) at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:91) at com.studerw.tda.parse.TdaJsonParser.parseOptionChain(TdaJsonParser.java:218) at com.studerw.tda.client.HttpTdaClient.getOptionChain(HttpTdaClient.java:595) at com.hpi.appcontrollers.TDAmeritradeFetchOptionsController2.doPrices(TDAmeritradeFetchOptionsController2.java:52) at com.hpi.appcontrollers.CmdLineController.doCommandLine(CmdLineController.java:238) at com.hpi.appcontrollers.AppController.startApp(AppController.java:56) at com.hpi.appTPCcli.TPCcliEx.main(TPCcliEx.java:19)

followed by

Caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type com.studerw.tda.model.account.OptionDeliverable$AssetType from String "STOCK": not one of the values accepted for Enum class: [MUTUAL_FUND, CURRENCY, INDEX, FIXED_INCOME, OPTION, CASH_EQUIVALENT, EQUITY] at [Source: (BufferedInputStream); line: 1, column: 57843] (through reference chain: com.studerw.tda.model.option.OptionChain["callExpDateMap"]->java.util.LinkedHashMap["2021-01-15:9"]->java.util.LinkedHashMap["23.0"]->java.util.ArrayList[0]->com.studerw.tda.model.option.Option["optionDeliverablesList"]->java.util.ArrayList[1]->com.studerw.tda.model.account.OptionDeliverable["assetType"]) at com.fasterxml.jackson.databind.exc.InvalidFormatException.from(InvalidFormatException.java:67) at com.fasterxml.jackson.databind.DeserializationContext.weirdStringException(DeserializationContext.java:1698) at com.fasterxml.jackson.databind.DeserializationContext.handleWeirdStringValue(DeserializationContext.java:947) at com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeAltString(EnumDeserializer.java:255) at com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:179) at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:285) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27) at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:285) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:244) at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27) at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBind(MapDeserializer.java:465) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:367) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) at com.fasterxml.jackson.databind.deser.std.MapDeserializer._readAndBindStringKeyMap(MapDeserializer.java:527) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:364) at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserialize(MapDeserializer.java:29) at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:138) at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:293) at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:156) at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4482) at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3479) at com.studerw.tda.parse.DefaultMapper.fromJson(DefaultMapper.java:89) ... 6 more

Order.getStatus() returns null

Immediately after calling client.placeOrder() a call to order.getStatus returns null. This is unexpected. Shouldn't it return a Status instance? The call to placeOrder() places an order and seems to work as expected.

No definition for "client id"

The wiki refers to a "client id". I can't see where this is defined or any description of where it comes from. The wiki references the "Getting Started" page at TD Ameritrade, but the page linked says nothing about a "client id". One clue is that the wiki says it is created "when you register your app". After registering the app and successfully getting a refresh token I cannot find a "client id" anywhere. They are providing a "consumer key". Could this be it? An account also has an account number and a login ID. Are any of these a "client id"?

Thanks!

Option Chain Parse failure from getOptionChain()

Hi,

I am getting the following exception from getOptionChain() when I issued it today for OSTK. Could you please check this issue? I just tested with 2.4.0. If you cannot reproduce with OSTK, I can try to find other symbol that has the same issue.

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.math.BigDecimal from String "NaN": not a valid representation
at [Source: (BufferedInputStream); line: 1, column: 681] (through reference chain: com.studerw.tda.model.option.OptionChain["putExpDateMap"]->java.util.LinkedHashMap["2021-02-12:3"]->java.util.LinkedHashMap["46.0"]->java.util.ArrayList[0]->com.studerw.tda.model.option.Option["volatility"])

Thank you!

fetchQuotes method requires a refresh token

Hi,

Thank you for coming up with this API. I find the TD Ameritrade API cumbersome and I'm still learning how this API works too. :-)

This issue is more of an enhancement request but it would be very beneficial to users that just want to use your API to get quotes and nothing more. This whole idea of using a refresh_token (that expires every 90 days) in your application is painful if you just want to get quotes.

Looking at the underlying quote API that this method uses:

https://developer.tdameritrade.com/quotes/apis/get/marketdata/quotes

It doesn't require anything but an apikey (Consumer Key). It would be great in this case if calls to fetchQuotes didn't require a refresh_token as it's not required. For example:

https://api.tdameritrade.com/v1/marketdata/quotes?apikey=<your app's consumer key>&symbol=IBM,MSFT

always works and doesn't require a refresh_token.

Thanks

Streaming API

Hi,

This is not really an issue. I just wanted to check with you whether you have any plans to add streaming API to your client.

Thanks

Duplicate class / NoSuchMethodError

I'm trying to use this library on Android 10, but I get a lot of build errors:

Duplicate class javax.validation.BootstrapConfiguration found in modules jetified-jakarta.validation-api-2.0.2 (jakarta.validation:jakarta.validation-api:2.0.2) and jetified-validation-api-2.0.1.Final (javax.validation:validation-api:2.0.1.Final)
Duplicate class javax.validation.ClockProvider found in modules jetified-jakarta.validation-api-2.0.2 (jakarta.validation:jakarta.validation-api:2.0.2) and jetified-validation-api-2.0.1.Final (javax.validation:validation-api:2.0.1.Final)
Duplicate class javax.validation.Configuration found in modules jetified-jakarta.validation-api-2.0.2 (jakarta.validation:jakarta.validation-api:2.0.2) and jetified-validation-api-2.0.1.Final (javax.validation:validation-api:2.0.1.Final)
(many more similar lines)

I have tried to get around this by specifying the dependency like this:

implementation ("com.studerw.tda:td-ameritrade-client:2.4.0") {
    exclude group: "javax.validation"
}

This makes the build successful and I'm able to use some parts of the library, but when I try to call client.fetchTransactions() then I get a runtime error:

java.lang.NoSuchMethodError: No virtual method getAnnotatedInterfaces()[Ljava/lang/reflect/AnnotatedType; in class Ljava/lang/Class; or its super classes (declaration of 'java.lang.Class' appears in /apex/com.android.runtime/javalib/core-oj.jar)

Any suggestions on how to get it working on Android?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.