Skip to content

Commit f139d41

Browse files
authored
Merge pull request #6 from tradovate/alex-patch-2
Fixed missing files, various minor fixes.
2 parents 3a96565 + d8bd391 commit f139d41

File tree

32 files changed

+1866
-143
lines changed

32 files changed

+1866
-143
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { connect } from './connect'
2+
import { tvGet, tvPost } from './services'
23

34
//uncomment the next line to test it
4-
//connect()
5+
//connect()

tutorial/Access/EX-0-Access-Start/src/services.js

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
import { getAccessToken } from './storage'
22
import { URLs } from '../../../tutorialsURLs'
33

4-
const { DEMO_URL } = URLs
4+
const { DEMO_URL, LIVE_URL } = URLs
55

6-
export const tvGet = async (endpoint, query = null) => {
6+
/**
7+
* Call to make GET requests to the Tradovate REST API. The passed `query` object will be reconstructed to a query string and placed in the query position of the URL.
8+
* ```js
9+
* //no parameters
10+
* const jsonResponseA = await tvGet('/account/list')
11+
*
12+
* //parameter object, URL will become '/contract/item?id=2287764'
13+
* const jsonResponseB = await tvGet('/contract/item', { id: 2287764 })
14+
* ```
15+
*
16+
* New! You can interact with the browser devolopers' console. In the console enter commands:
17+
* ```
18+
* > tradovate.get('/account/list') //=> account data []
19+
* > tradovate.get('/contract/item', {id: 12345}) //=> maybe contract
20+
* ```
21+
*
22+
* @param {string} endpoint
23+
* @param {{[k:string]: any}} query object key-value-pairs will be converted into query, for ?masterid=1234 use `{masterid: 1234}`
24+
* @param {'demo' | 'live'} env
25+
* @returns
26+
*/
27+
export const tvGet = async (endpoint, query = null, env = 'demo') => {
728
const { token } = getAccessToken()
829
try {
930
let q = ''
@@ -15,10 +36,14 @@ export const tvGet = async (endpoint, query = null) => {
1536
}, '?')
1637
}
1738

18-
console.log(q.toString())
39+
console.log('With query:', q.toString() || '<no query>')
40+
41+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
42+
if(!baseURL) throw new Error(`[Services:tvGet] => 'env' variable should be either 'live' or 'demo'.`)
43+
1944
let url = query !== null
20-
? DEMO_URL + endpoint + q
21-
: DEMO_URL + endpoint
45+
? baseURL + endpoint + q
46+
: baseURL + endpoint
2247

2348
console.log(url)
2449

@@ -40,11 +65,36 @@ export const tvGet = async (endpoint, query = null) => {
4065
}
4166
}
4267

43-
export const tvPost = async (endpoint, data, _usetoken = true) => {
68+
/**
69+
* Use this function to make POST requests to the Tradovate REST API. `data` will be placed in the body of the request as JSON.
70+
* ```js
71+
* //placing an order with tvPost
72+
* const jsonResponseC = await tvPost('/order/placeorder', {
73+
* accountSpec: myAcct.name,
74+
* accountId: myAcct.id,
75+
* action: 'Buy',
76+
* symbol: 'MNQM1',
77+
* orderQty: 2,
78+
* orderType: 'Market',
79+
* isAutomated: true //was this order placed by you or your robot?
80+
* })
81+
* ```
82+
*
83+
* @param {string} endpoint
84+
* @param {{[k:string]: any}} data
85+
* @param {boolean} _usetoken
86+
* @param {'live' | 'demo'} env
87+
* @returns
88+
*/
89+
export const tvPost = async (endpoint, data, _usetoken = true, env = 'demo') => {
4490
const { token } = getAccessToken()
4591
const bearer = _usetoken ? { Authorization: `Bearer ${token}` } : {}
92+
93+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
94+
if(!baseURL) throw new Error(`[Services:tvPost] => 'env' variable should be either 'live' or 'demo'.`)
95+
4696
try {
47-
const res = await fetch(DEMO_URL + endpoint, {
97+
const res = await fetch(baseURL + endpoint, {
4898
method: 'POST',
4999
headers: {
50100
...bearer,
@@ -63,3 +113,8 @@ export const tvPost = async (endpoint, data, _usetoken = true) => {
63113
}
64114
}
65115

116+
//New! Interact with the API via browser console.
117+
window.tradovate = {
118+
get: tvGet,
119+
post: tvPost
120+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
const STORAGE_KEY = 'tradovate-api-access-token'
2+
const EXPIRATION_KEY = 'tradovate-api-access-expiration'
3+
const DEVICE_ID_KEY = 'tradovate-device-id'
4+
const AVAIL_ACCTS_KEY = 'tradovate-api-available-accounts'
5+
6+
export const setAvailableAccounts = accounts => {
7+
sessionStorage.setItem(AVAIL_ACCTS_KEY, JSON.stringify(accounts))
8+
}
9+
10+
/**
11+
* Returns and array of available accounts or undefined.
12+
* @returns Account[]
13+
*/
14+
export const getAvailableAccounts = () => {
15+
return JSON.parse(sessionStorage.getItem(JSON.parse(AVAIL_ACCTS_KEY)))
16+
}
17+
18+
/**
19+
* Use a predicate function to find an account. May be undefined.
20+
*/
21+
export const queryAvailableAccounts = predicate => {
22+
return getAvailableAccounts().find(predicate)
23+
}
24+
25+
export const setDeviceId = (id) => {
26+
sessionStorage.setItem(DEVICE_ID_KEY, id)
27+
}
28+
29+
export const getDeviceId = () => {
30+
return sessionStorage.getItem(DEVICE_ID_KEY)
31+
}
32+
33+
export const setAccessToken = (token, expiration) => {
34+
//if(!token || !expiration) throw new Error('attempted to set undefined token')
35+
sessionStorage.setItem(STORAGE_KEY, token)
36+
sessionStorage.setItem(EXPIRATION_KEY, expiration)
37+
}
38+
39+
export const getAccessToken = () => {
40+
const token = sessionStorage.getItem(STORAGE_KEY)
41+
const expiration = sessionStorage.getItem(EXPIRATION_KEY)
42+
if(!token) {
43+
console.warn('No access token retrieved. Please request an access token.')
44+
}
45+
return { token, expiration }
46+
}
47+
48+
export const tokenIsValid = expiration => new Date(expiration) - new Date() > 0

tutorial/Access/EX-1-Simple-Request/src/services.js

Lines changed: 56 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,24 @@
11
import { getAccessToken } from './storage'
22
import { URLs } from '../../../tutorialsURLs'
33

4-
const { DEMO_URL } = URLs
4+
const { DEMO_URL, LIVE_URL } = URLs
55

6-
export const tvGet = async (endpoint, query = null) => {
6+
/**
7+
* Call to make GET requests to the Tradovate REST API. The passed `query` object will be reconstructed to a query string and placed in the query position of the URL.
8+
* ```js
9+
* //no parameters
10+
* const jsonResponseA = await tvGet('/account/list')
11+
*
12+
* //parameter object, URL will become '/contract/item?id=2287764'
13+
* const jsonResponseB = await tvGet('/contract/item', { id: 2287764 })
14+
* ```
15+
*
16+
* @param {string} endpoint
17+
* @param {{[k:string]: any}} query object key-value-pairs will be converted into query, for ?masterid=1234 use `{masterid: 1234}`
18+
* @param {'demo' | 'live'} env
19+
* @returns
20+
*/
21+
export const tvGet = async (endpoint, query = null, env = 'demo') => {
722
const { token } = getAccessToken()
823
try {
924
let q = ''
@@ -15,10 +30,14 @@ export const tvGet = async (endpoint, query = null) => {
1530
}, '?')
1631
}
1732

18-
console.log(q.toString())
33+
console.log('With query:', q.toString() || '<no query>')
34+
35+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
36+
if(!baseURL) throw new Error(`[Services:tvGet] => 'env' variable should be either 'live' or 'demo'.`)
37+
1938
let url = query !== null
20-
? DEMO_URL + endpoint + q
21-
: DEMO_URL + endpoint
39+
? baseURL + endpoint + q
40+
: baseURL + endpoint
2241

2342
console.log(url)
2443

@@ -33,20 +52,43 @@ export const tvGet = async (endpoint, query = null) => {
3352

3453
const js = await res.json()
3554

36-
// console.log(js)
37-
3855
return js
3956

4057
} catch(err) {
4158
console.error(err)
4259
}
4360
}
4461

45-
export const tvPost = async (endpoint, data, _usetoken = true) => {
62+
/**
63+
* Use this function to make POST requests to the Tradovate REST API. `data` will be placed in the body of the request as JSON.
64+
* ```js
65+
* //placing an order with tvPost
66+
* const jsonResponseC = await tvPost('/order/placeorder', {
67+
* accountSpec: myAcct.name,
68+
* accountId: myAcct.id,
69+
* action: 'Buy',
70+
* symbol: 'MNQM1',
71+
* orderQty: 2,
72+
* orderType: 'Market',
73+
* isAutomated: true //was this order placed by you or your robot?
74+
* })
75+
* ```
76+
*
77+
* @param {string} endpoint
78+
* @param {{[k:string]: any}} data
79+
* @param {boolean} _usetoken
80+
* @param {'live' | 'demo'} env
81+
* @returns
82+
*/
83+
export const tvPost = async (endpoint, data, _usetoken = true, env = 'demo') => {
4684
const { token } = getAccessToken()
4785
const bearer = _usetoken ? { Authorization: `Bearer ${token}` } : {}
86+
87+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
88+
if(!baseURL) throw new Error(`[Services:tvPost] => 'env' variable should be either 'live' or 'demo'.`)
89+
4890
try {
49-
const res = await fetch(DEMO_URL + endpoint, {
91+
const res = await fetch(baseURL + endpoint, {
5092
method: 'POST',
5193
headers: {
5294
...bearer,
@@ -58,12 +100,15 @@ export const tvPost = async (endpoint, data, _usetoken = true) => {
58100

59101
const js = await res.json()
60102

61-
// console.log(js)
62-
63103
return js
64104

65105
} catch(err) {
66106
console.error(err)
67107
}
68108
}
69109

110+
//New! Interact with the API via browser console.
111+
window.tradovate = {
112+
get: tvGet,
113+
post: tvPost
114+
}

tutorial/Access/EX-2-Storing-A-Token/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
## Storing a Token
22
Now that we now how to get an access token, we really should store it locally. Fortunately, included with this project is a file called `storage.js`. This additional file contains functions that will let you set and retrieve items using `sessionStorage`. Using `sessionStorage` ensures that our temporary tokens will be cleared at the end of the session, and it also means that our apps will work even in browsers' Incognito mode.
33

4+
> **Quick Tip!** From this section forward, you can use the developers' console to play with Tradovate REST API requests directly. Simply type `tradovate.get` or `tradovate.post` in the browser. These are functions that match `tvGet` or `tvPost` respectively, from `services.js`.
5+
46
Let's see how our storage functions work. In `connect.js` we will make some changes:
57

68
```javascript

tutorial/Access/EX-2-Storing-A-Token/src/services.js

Lines changed: 62 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,30 @@
11
import { getAccessToken } from './storage'
22
import { URLs } from '../../../tutorialsURLs'
33

4-
const { DEMO_URL } = URLs
4+
const { DEMO_URL, LIVE_URL } = URLs
55

6-
export const tvGet = async (endpoint, query = null) => {
6+
/**
7+
* Call to make GET requests to the Tradovate REST API. The passed `query` object will be reconstructed to a query string and placed in the query position of the URL.
8+
* ```js
9+
* //no parameters
10+
* const jsonResponseA = await tvGet('/account/list')
11+
*
12+
* //parameter object, URL will become '/contract/item?id=2287764'
13+
* const jsonResponseB = await tvGet('/contract/item', { id: 2287764 })
14+
* ```
15+
*
16+
* New! You can interact with the browser devolopers' console. In the console enter commands:
17+
* ```
18+
* > tradovate.get('/account/list') //=> account data []
19+
* > tradovate.get('/contract/item', {id: 12345}) //=> maybe contract
20+
* ```
21+
*
22+
* @param {string} endpoint
23+
* @param {{[k:string]: any}} query object key-value-pairs will be converted into query, for ?masterid=1234 use `{masterid: 1234}`
24+
* @param {'demo' | 'live'} env
25+
* @returns
26+
*/
27+
export const tvGet = async (endpoint, query = null, env = 'demo') => {
728
const { token } = getAccessToken()
829
try {
930
let q = ''
@@ -15,10 +36,14 @@ export const tvGet = async (endpoint, query = null) => {
1536
}, '?')
1637
}
1738

18-
console.log(q.toString())
39+
console.log('With query:', q.toString() || '<no query>')
40+
41+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
42+
if(!baseURL) throw new Error(`[Services:tvGet] => 'env' variable should be either 'live' or 'demo'.`)
43+
1944
let url = query !== null
20-
? DEMO_URL + endpoint + q
21-
: DEMO_URL + endpoint
45+
? baseURL + endpoint + q
46+
: baseURL + endpoint
2247

2348
console.log(url)
2449

@@ -40,11 +65,36 @@ export const tvGet = async (endpoint, query = null) => {
4065
}
4166
}
4267

43-
export const tvPost = async (endpoint, data, _usetoken = true) => {
68+
/**
69+
* Use this function to make POST requests to the Tradovate REST API. `data` will be placed in the body of the request as JSON.
70+
* ```js
71+
* //placing an order with tvPost
72+
* const jsonResponseC = await tvPost('/order/placeorder', {
73+
* accountSpec: myAcct.name,
74+
* accountId: myAcct.id,
75+
* action: 'Buy',
76+
* symbol: 'MNQM1',
77+
* orderQty: 2,
78+
* orderType: 'Market',
79+
* isAutomated: true //was this order placed by you or your robot?
80+
* })
81+
* ```
82+
*
83+
* @param {string} endpoint
84+
* @param {{[k:string]: any}} data
85+
* @param {boolean} _usetoken
86+
* @param {'live' | 'demo'} env
87+
* @returns
88+
*/
89+
export const tvPost = async (endpoint, data, _usetoken = true, env = 'demo') => {
4490
const { token } = getAccessToken()
4591
const bearer = _usetoken ? { Authorization: `Bearer ${token}` } : {}
92+
93+
let baseURL = env === 'demo' ? DEMO_URL : env === 'live' ? LIVE_URL : ''
94+
if(!baseURL) throw new Error(`[Services:tvPost] => 'env' variable should be either 'live' or 'demo'.`)
95+
4696
try {
47-
const res = await fetch(DEMO_URL + endpoint, {
97+
const res = await fetch(baseURL + endpoint, {
4898
method: 'POST',
4999
headers: {
50100
...bearer,
@@ -63,3 +113,8 @@ export const tvPost = async (endpoint, data, _usetoken = true) => {
63113
}
64114
}
65115

116+
//New! Interact with the API via browser console.
117+
window.tradovate = {
118+
get: tvGet,
119+
post: tvPost
120+
}

0 commit comments

Comments
 (0)