In the Solution Explorer right-click the project and select Properties. Go to the “Settings” tab and create a “SettingInterval”. Make the type “int” for the SettingInterval.
public frmMain() { InitializeComponent(); timer1.Tick += Timer1_Tick; timer1.Interval = 1000; } private void Timer1_Tick(object sender, EventArgs e) { TimeSpan ts = Expires – DateTime.Now; if (ts.TotalSeconds < 10) if (Warning) { Warning = false; // this must be before the MessageBox btnLogIn.BackColor = Color.Orange; MessageBox.Show(“You have 30 seconds left!”); }
}
I have a button which will trigger the timer.
private void btnLogIn_Click(object sender, EventArgs e) { int NewInterval = 30; //30 min……AccessToken expired in 30 min Properties.Settings.Default.SettingInterval = NewInterval; Expires = DateTime.Now.AddMinutes(NewInterval); Warning = true; timer1.Start();
I’m writing this guide so that the community has something with screenshots that is easy to follow. There were several points in the guide u/carlos85333 wrote that confused me (no offense, I’m insanely grateful for you writing that and it could have just been differences in the way we communicate, or the fact that I drink too much coffee and stay up until odd hours… I digress). I worked as a software analyst for 2 years and this process still got the best of me so hopefully I can help save someone else the trouble if they can see what this actually looks like. u/carlos85333 has some extra goodies pertaining to custom watchlist scans in his thread as well. You should go read that if you haven’t already.
I have included screenshots to make things as straightforward as possible because the instructions on the TD Ameritrade site are absolutely horrendous. This entire process is ridiculous really when in crypto space it’s a about three clicks and you’re done… rant for another day though. This guide assumes you have a TD Ameritrade CLIENT account, meaning a banking or trading account already. If not, go open a trading account with them. It’s free (no deposit ever required to my knowledge) and… well it’s not painless but that’s just how opening a trading account is. It also assumes you are using a Windows OS. If you aren’t you will need to figure out the temporary localhost webserver on your own. I don’t care to open that can of worms here.
If any of this is broken please let me know and I’ll try to correct it.
Temporarily Enabling IIS:
1. This process requires that one of the requests actually be made from your callback url. If you don’t know what that means it’s safe to assume you need to enable the web server on your computer. You can turn it off when you are finished.
2. Go to: Control Panel > Programs > Turn Windows Features on or off > Click “Internet Information Services”
3. It will put a box in the box. Click “OK” and let windows do it’s thing.
4. In a browser go to http://localhost. You should get a generic “Internet Information Services” page. If you do, great. If not press Ctrl+F5 to force a full refresh. If still now, google how to turn IIS web server on, that is outside the scope of this document.
5. Once you have completed the Getting Access section you can go back in and disable this feature.
Paste in your Callback URL (http://localhost in our example) and click ENCODE.
This replaces the colon and slashes with %3A and %2F respectively so they can be passed in a URL). Copy the result to notepad, it should be “http%3A%2F%2Flocalhost” without quotes if you are following this guide to the letter.
12. Now, replace the parts in {brackets} of the following link with your URL encoded Callback URL and your Consumer Key. The consumer key should not need to be encoded as it should just be letters and numbers. The TD Ameritrade documentation is wrong.
14. Paste this into your browser and click go or hit Enter. If the URL was formed correctly it should take you to a “Secure Log-In” page. You need to log in with a TD Ameritrade CLIENT account. NOT a developer account. In other words you need to open a banking or trading account with TD Ameritrade if you don’t already have one. It’s not difficult and it doesn’t cost anything but that is outside the scope of this document. Side note, the input fields on this login page freeze sometimes for me (using Chrome) and I have to just click in the box and type until they start working.
15. Once you have logged in click the “Allow” button. You WILL get a “This site can’t be reached error” This is normal and expected.
16. Copy the entire contents of the address bar into notepad. Remove the beginning up to and including the equal sign after the word code.
18. Paste that long string of gobbledygook (everything you saved after the “code=” part) into the DECODER and click DECODE. Copy the result and save that to notepad. This is your Refresh Token
grant_type: authorization_code (literally type "authorization_code" into the box without quotes)
refresh_token: (leave blank - I know... none of the labeling makes sense, just trust me)
acccess_type: offline (same as above, literally type "offline" into the box without quotes)
code: decodedStuffFromStep18
client_id: CONSUMERKEY@AMER.OAUTHAP (yes, add "@AMER.OAUTHAP" without quotes)
redirect_uri: http://localhost
20. Click “SEND”. If everything went well you should get an “HTTP/1.1 200 OK” response. If you scroll down it will contain your access_token. Copy it to notepad. Save it.
21. Take a break. That was exhausting.
Getting Data:
I’m not going to go too far into this as anything pertaining to actually utilizing the API is outside the scope of this document (I also wouldn’t be able to help, I’m still figuring it out myself) but I do want to at least get you started.
apikey: CONSUMERKEY (without the @AMER.OAUTHAP this time for some reason… this took some trial and error)
click send. You should receive an “HTTP/1.1 200” response with the quote data
Common known issue and solution:
“code” or “authorization code” is only a one-time pass-key that expires after 30 minutes. It allows you to get the “access token”, which, although it has a similar name, seems to be different. So make sure you URL-decode the auth code reasonably rapidly, then get your first response correctly in before 30 minutes.
Also try on weekends, as TDAmeritrade’s SMS gateway has been frustratingly slow recently during the GameStop raids, and it’s possible their authentication handshaking could be having problems as well during trading hours.
Note that appending “@AMER.OAUTHAP” does not seem to be necessary for the client_id slot of the manual Post Access Token form.
SELECT s.session_id AS 'SessionId',
s.login_name AS 'Login',
COALESCE(s.host_name, c.client_net_address) AS 'Host',
s.program_name AS 'Application',
t.task_state AS 'TaskState',
r.start_time AS 'TaskStartTime',
r.[status] AS 'TaskStatus',
r.wait_type AS 'TaskWaitType',
TSQL.[text] AS 'TSQL',
(
tsu.user_objects_alloc_page_count - tsu.user_objects_dealloc_page_count
) +(
tsu.internal_objects_alloc_page_count - tsu.internal_objects_dealloc_page_count
) AS 'TotalPagesAllocated'
FROM sys.dm_exec_sessions s
LEFT JOIN sys.dm_exec_connections c
ON s.session_id = c.session_id
LEFT JOIN sys.dm_db_task_space_usage tsu
ON tsu.session_id = s.session_id
LEFT JOIN sys.dm_os_tasks t
ON t.session_id = tsu.session_id
AND t.request_id = tsu.request_id
LEFT JOIN sys.dm_exec_requests r
ON r.session_id = tsu.session_id
AND r.request_id = tsu.request_id
OUTER APPLY sys.dm_exec_sql_text(r.sql_handle) TSQL
WHERE (
tsu.user_objects_alloc_page_count - tsu.user_objects_dealloc_page_count
) +(
tsu.internal_objects_alloc_page_count - tsu.internal_objects_dealloc_page_count
) > 0;
--kill 80