studerw / td-ameritrade-client

TD Ameritrade Java Client
Apache License 2.0
69 stars 47 forks source link

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

Open Kofi-D-Boateng opened 1 year ago

Kofi-D-Boateng commented 1 year ago

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

studerw commented 1 year ago

Hi @Kofi-D-Boateng

Before you try with something this complicated i.e. the cache of multiple clients, have you tried a very simple flow with just your own TDA prop? For example, generate your refresh_token and see if you can get this simple project to run: TDA Client Example? Because it's likely you're using invalid refresh token which can be very difficult to generate. Whenever my own expires and I have to generate a new one, it often takes me more than one try to create a new one that works correctly. You can look here to see how I do it: Create TDA Refresh Token.

Also, in your code you're doing this weird thing where you are creating property files in the class path for each unique user (whom I assume has already generated their refresh token correctly). You shouldn't do that because I'm not even sure that is the correct location for that file when you're running within the application (it will depend on where you started the app, etc).

Instead, you can just create a Java properties and pass that to the HttpTdaClient constructor.

Finally, don't know if you're aware but TDA is moving all their accounts over to Schwab, which bought TDA last year. When they do that for each account, this API will no longer work for the account, AFAICT.

I myself just got a notice that my account is moving on September 1st, so I don't know how much longer the TDA Api will even work for my own account.

So I wouldn't spend too much time on this project since it's likely to not even work within a few months. Whether Schwab creates a new API is not yet known. And I doubt it would be backwards compatible anyway. Sorry :(

Kofi-D-Boateng commented 1 year ago

Thank you for the quick response!

Regarding the writing to the properties file, I only because it looked like the interceptor was might have reading from a file and I saw some mentioning of creating it in the resource file, so I wanted to try that first to see what exactly the correct flow was, but I think I figured out my main issue. The appending of @AMER.OAUTHAP is most likely the issue. I am going to retry it again here shortly and see if that is the case. I was following some other tutorial that was in python but most of it applies directly to Java.

Also, I was aware of the Schwab merger, but they have not made any updates with how far along they are regarding the api, but I saw something about the Schwab API in the docs. I will wait and see what becomes of it. Luckily this project was just a mini side project for my portfolio in which I just needed any API to test my trading strategies and possibly have some friends use your API to automate their trading, so my next question is do you plan to work on a new API wrapper when the smoke clears, whether solo or joint with someone? If not, that is also understandable and thank you for you time and effort!