tradestation-client 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../authMiddleware.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAM/C,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,QAAQ,GAAG,YAAY,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAQD,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAO5D;AAgJD,wBAAsB,YAAY,CAChC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,QAAQ,CAAC,CAkBnB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,GACnB,UAAU,CAmCZ"}
1
+ {"version":3,"file":"authMiddleware.d.ts","sourceRoot":"","sources":["../authMiddleware.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAO/C,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,KAAK,QAAQ,GAAG,YAAY,GAAG;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,aAAa,EAAE,MAAM,CAAA;CACtB,CAAA;AAQD,wBAAsB,WAAW,IAAI,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAO5D;AA8HD,wBAAsB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAkB5F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CA6BvF"}
@@ -3,7 +3,8 @@ import { readFile, writeFile } from 'node:fs/promises';
3
3
  import { join } from 'node:path';
4
4
  import fastify from 'fastify';
5
5
  import open from 'open';
6
- import { redirectPort, redirectUri } from './config.js';
6
+ const redirectPort = 31022;
7
+ const redirectUri = `http://localhost:${redirectPort}`;
7
8
  const authFilePath = join(process.cwd(), 'tradestation-auth.json');
8
9
  function generateRandomState() {
9
10
  return randomBytes(32).toString('base64url');
@@ -1 +1 @@
1
- {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../authMiddleware.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../authMiddleware.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import type { paths } from './generated/tradestation-api.js';
2
2
  export declare function createTradeStationClient(clientId: string, clientSecret: string): import("openapi-fetch").Client<paths, `${string}/${string}`>;
3
- //# sourceMappingURL=tradestation-client.d.ts.map
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAG5D,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,gEAOrB"}
@@ -7,4 +7,4 @@ export function createTradeStationClient(clientId, clientSecret) {
7
7
  client.use(createAuthMiddleware(clientId, clientSecret));
8
8
  return client;
9
9
  }
10
- //# sourceMappingURL=tradestation-client.js.map
10
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,UAAU,wBAAwB,CACtC,QAAgB,EAChB,YAAoB;IAEpB,MAAM,MAAM,GAAG,YAAY,CAAQ;QACjC,OAAO,EAAE,8BAA8B;KACxC,CAAC,CAAA;IACF,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAA;IACxD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloadOpenAPI.d.ts","sourceRoot":"","sources":["../../scripts/downloadOpenAPI.ts"],"names":[],"mappings":""}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"downloadOpenAPI.js","sourceRoot":"","sources":["../../scripts/downloadOpenAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE1C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,CAAC,sBAAsB,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;AAEpC,MAAM,IAAI,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;AAEnE,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAA;AAE1C,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;AAErD,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;AAE1D,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAA;AACtC,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;AAE5C,IAAI,cAAc,EAAE,CAAC;IACnB,MAAM,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC,CAAA;IACnE,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;IAC5B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;AAC1D,CAAC;KAAM,CAAC;IACN,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA"}
package/dist/spike.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import process from 'node:process';
2
2
  process.loadEnvFile();
3
- import { createTradeStationClient } from './tradestation-client.js';
3
+ import { createTradeStationClient } from './index.js';
4
4
  const tradestationClient = createTradeStationClient(process.env.CLIENT_ID, process.env.CLIENT_SECRET);
5
5
  const { data } = await tradestationClient.GET('/v3/marketdata/stream/barcharts/{symbol}', {
6
6
  params: {
package/dist/spike.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"spike.js","sourceRoot":"","sources":["../spike.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,CAAC,WAAW,EAAE,CAAA;AAErB,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAA;AAEnE,MAAM,kBAAkB,GAAG,wBAAwB,CACjD,OAAO,CAAC,GAAG,CAAC,SAAU,EACtB,OAAO,CAAC,GAAG,CAAC,aAAc,CAC3B,CAAA;AAED,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAC3C,0CAA0C,EAC1C;IACE,MAAM,EAAE;QACN,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACvB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,GAAG;YACb,eAAe,EAAE,YAAY;SAC9B;KACF;IACD,OAAO,EAAE,QAAQ;CAClB,CACF,CAAA;AAED,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAK,EAAE,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9C,CAAC"}
1
+ {"version":3,"file":"spike.js","sourceRoot":"","sources":["../spike.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,cAAc,CAAA;AAElC,OAAO,CAAC,WAAW,EAAE,CAAA;AAErB,OAAO,EAAE,wBAAwB,EAAE,MAAM,YAAY,CAAA;AAErD,MAAM,kBAAkB,GAAG,wBAAwB,CAAC,OAAO,CAAC,GAAG,CAAC,SAAU,EAAE,OAAO,CAAC,GAAG,CAAC,aAAc,CAAC,CAAA;AAEvG,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,kBAAkB,CAAC,GAAG,CAAC,0CAA0C,EAAE;IACxF,MAAM,EAAE;QACN,IAAI,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;QACvB,KAAK,EAAE;YACL,QAAQ,EAAE,GAAG;YACb,IAAI,EAAE,QAAQ;YACd,QAAQ,EAAE,GAAG;YACb,eAAe,EAAE,YAAY;SAC9B;KACF;IACD,OAAO,EAAE,QAAQ;CAClB,CAAC,CAAA;AAEF,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,IAAK,EAAE,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AAC9C,CAAC"}
package/package.json CHANGED
@@ -1,25 +1,28 @@
1
1
  {
2
2
  "name": "tradestation-client",
3
- "version": "1.1.0",
3
+ "version": "1.1.2",
4
4
  "description": "A Node.js client for the TradeStation API with OAuth2 authentication and OpenAPI integration.",
5
5
  "type": "module",
6
+ "main": "./dist/index.js",
6
7
  "bin": "./dist/cli.js",
8
+ "files": [
9
+ "dist"
10
+ ],
7
11
  "scripts": {
8
12
  "test": "tsx --experimental-test-module-mocks --test",
9
- "test:ts": "tsc --noEmit",
10
13
  "cli": "tsx cli.ts",
11
- "download-openapi": "node ./downloadOpenAPI.ts",
12
- "generate-client": "openapi-typescript ./openapi.json --output generated/tradestation-api.d.ts",
13
- "build": "npm run download-openapi && npm run generate-client && tsc",
14
+ "download-openapi": "node scripts/downloadOpenAPI.ts",
15
+ "generate-client": "openapi-typescript openapi.json --output generated/tradestation-api.d.ts",
16
+ "build": "npm run download-openapi && npm run generate-client && rimraf dist && tsc",
14
17
  "prepublishOnly": "npm run build"
15
18
  },
16
19
  "keywords": [],
17
- "author": "",
20
+ "author": "Simone Busoli <simone.busoli@gmail.com>",
21
+ "repository": "github:simoneb/tradestation-client",
18
22
  "dependencies": {
19
23
  "commander": "^14.0.2",
20
24
  "fastify": "^5.6.2",
21
25
  "install": "^0.13.0",
22
- "npm": "^11.7.0",
23
26
  "open": "^11.0.0",
24
27
  "openapi-fetch": "^0.15.0",
25
28
  "tradestation-api-ts": "^1.2.1"
@@ -28,6 +31,7 @@
28
31
  "@types/node": "^25.0.3",
29
32
  "openapi-typescript": "^7.10.1",
30
33
  "playwright-core": "^1.57.0",
34
+ "rimraf": "^6.1.2",
31
35
  "tsx": "^4.21.0",
32
36
  "typescript": "^5.9.3"
33
37
  }
package/.env.example DELETED
@@ -1,2 +0,0 @@
1
- CLIENT_ID=
2
- CLIENT_SECRET=
package/.prettierrc DELETED
@@ -1,6 +0,0 @@
1
- {
2
- "singleQuote": true,
3
- "semi": false,
4
- "printWidth": 120,
5
- "arrowParens": "avoid"
6
- }
package/authMiddleware.ts DELETED
@@ -1,243 +0,0 @@
1
- import { randomBytes } from 'node:crypto'
2
- import { readFile, writeFile } from 'node:fs/promises'
3
- import { join } from 'node:path'
4
- import type { Middleware } from 'openapi-fetch'
5
- import fastify from 'fastify'
6
- import open from 'open'
7
-
8
- import { redirectPort, redirectUri } from './config.js'
9
-
10
- type AuthResponse = {
11
- access_token: string
12
- refresh_token: string
13
- id_token: string
14
- scope: string
15
- expires_in: number
16
- token_type: string
17
- }
18
-
19
- type AuthData = AuthResponse & {
20
- timestamp: number // Unix timestamp in milliseconds when token was obtained
21
- client_id: string
22
- client_secret: string
23
- }
24
-
25
- const authFilePath = join(process.cwd(), 'tradestation-auth.json')
26
-
27
- function generateRandomState(): string {
28
- return randomBytes(32).toString('base64url')
29
- }
30
-
31
- export async function tryLoadAuth(): Promise<AuthData | null> {
32
- try {
33
- const data = await readFile(authFilePath, 'utf-8')
34
- return JSON.parse(data)
35
- } catch {
36
- return null
37
- }
38
- }
39
-
40
- async function saveAuth(
41
- authResponse: AuthResponse,
42
- clientId: string,
43
- clientSecret: string
44
- ): Promise<AuthData> {
45
- const authData: AuthData = {
46
- ...authResponse,
47
- timestamp: Date.now(),
48
- client_id: clientId,
49
- client_secret: clientSecret,
50
- }
51
-
52
- await writeFile(authFilePath, JSON.stringify(authData, null, 2), 'utf-8')
53
- return authData
54
- }
55
-
56
- function isTokenValid(token: AuthData): boolean {
57
- const now = Date.now()
58
- const expiresAt = token.timestamp + token.expires_in * 1000
59
- // Consider token expired 30 seconds before actual expiration to account for clock skew
60
- return now < expiresAt - 30000
61
- }
62
-
63
- async function requestAccessToken(
64
- code: string,
65
- clientId: string,
66
- clientSecret: string
67
- ): Promise<AuthData> {
68
- const authRes = await fetch('https://signin.tradestation.com/oauth/token', {
69
- method: 'POST',
70
- headers: {
71
- 'Content-Type': 'application/x-www-form-urlencoded',
72
- },
73
- body: new URLSearchParams({
74
- grant_type: 'authorization_code',
75
- code,
76
- redirect_uri: redirectUri,
77
- client_id: clientId,
78
- client_secret: clientSecret,
79
- }),
80
- })
81
-
82
- const authResponse = (await authRes.json()) as AuthResponse
83
-
84
- if (!authRes.ok) {
85
- throw new Error(`Failed to obtain access token: ${authResponse}`)
86
- }
87
- return saveAuth(authResponse, clientId, clientSecret)
88
- }
89
-
90
- async function refreshAccessToken(
91
- refreshToken: string,
92
- clientId: string,
93
- clientSecret: string
94
- ): Promise<AuthData> {
95
- const authRes = await fetch('https://signin.tradestation.com/oauth/token', {
96
- method: 'POST',
97
- headers: {
98
- 'Content-Type': 'application/x-www-form-urlencoded',
99
- },
100
- body: new URLSearchParams({
101
- grant_type: 'refresh_token',
102
- client_id: clientId,
103
- client_secret: clientSecret,
104
- refresh_token: refreshToken,
105
- }),
106
- })
107
-
108
- if (!authRes.ok) {
109
- throw new Error(`Failed to refresh token: ${await authRes.text()}`)
110
- }
111
-
112
- const authResponse = (await authRes.json()) as AuthResponse
113
-
114
- // Preserve the original refresh token if a new one wasn't provided
115
- // (TradeStation doesn't rotate refresh tokens by default)
116
- if (!authResponse.refresh_token) {
117
- authResponse.refresh_token = refreshToken
118
- }
119
-
120
- return saveAuth(authResponse, clientId, clientSecret)
121
- }
122
-
123
- async function authenticateWithOAuth2(
124
- clientId: string,
125
- clientSecret: string
126
- ): Promise<AuthData> {
127
- const app = fastify()
128
- const state = generateRandomState()
129
-
130
- const authPromise = new Promise<AuthData>((resolve, reject) => {
131
- app.get('/', async (request, reply) => {
132
- const { code, state: callbackState } = request.query as {
133
- code?: string
134
- state?: string
135
- }
136
-
137
- if (!code) {
138
- reply.code(400)
139
- return 'No code provided'
140
- }
141
-
142
- if (callbackState !== state) {
143
- reply.code(401)
144
- reject(new Error('State parameter mismatch - possible CSRF attack'))
145
- return 'State validation failed'
146
- }
147
-
148
- resolve(await requestAccessToken(code, clientId, clientSecret))
149
-
150
- setTimeout(() => {
151
- app.close()
152
- }, 100)
153
-
154
- return 'Authorization successful! You can close this tab.'
155
- })
156
- })
157
-
158
- await app.listen({ port: redirectPort, host: 'localhost' })
159
-
160
- console.log('Opening browser for authentication...')
161
-
162
- await openAuthUrl(state, clientId)
163
-
164
- return authPromise
165
- }
166
-
167
- async function openAuthUrl(state: string, clientId: string) {
168
- const authUrl = new URL('https://signin.tradestation.com/authorize')
169
- authUrl.searchParams.append('response_type', 'code')
170
- authUrl.searchParams.append(
171
- 'scope',
172
- 'openid offline_access profile MarketData ReadAccount Trade Matrix'
173
- )
174
- authUrl.searchParams.append('redirect_uri', redirectUri)
175
- authUrl.searchParams.append('client_id', clientId)
176
- authUrl.searchParams.append('state', state)
177
- authUrl.searchParams.append('audience', 'https://api.tradestation.com')
178
-
179
- await open(authUrl.toString())
180
- }
181
-
182
- export async function authenticate(
183
- clientId: string,
184
- clientSecret: string
185
- ): Promise<AuthData> {
186
- const auth = await tryLoadAuth()
187
-
188
- if (!auth) {
189
- return authenticateWithOAuth2(clientId, clientSecret)
190
- }
191
-
192
- if (isTokenValid(auth)) {
193
- return auth
194
- }
195
-
196
- try {
197
- return await refreshAccessToken(auth.refresh_token, clientId, clientSecret)
198
- } catch (error) {
199
- console.error('Token refresh failed, starting OAuth flow:', error)
200
- }
201
-
202
- return authenticateWithOAuth2(clientId, clientSecret)
203
- }
204
-
205
- export function createAuthMiddleware(
206
- clientId: string,
207
- clientSecret: string
208
- ): Middleware {
209
- return {
210
- async onRequest({ request }) {
211
- const auth = await authenticate(clientId, clientSecret)
212
-
213
- request.headers.set('Authorization', `Bearer ${auth.access_token}`)
214
- return request
215
- },
216
- async onResponse({ response, request }) {
217
- if (response.status === 401) {
218
- console.warn(
219
- `Received 401 Unauthorized for request to ${request.url}. Access token may be invalid or expired.`
220
- )
221
-
222
- let auth = await tryLoadAuth()
223
- if (!auth) {
224
- throw new Error('No authentication data available to refresh token.')
225
- }
226
-
227
- auth = await refreshAccessToken(
228
- auth.refresh_token,
229
- clientId,
230
- clientSecret
231
- )
232
-
233
- response = await fetch(new Request(request), {
234
- headers: {
235
- Authorization: `Bearer ${auth.access_token}`,
236
- },
237
- })
238
-
239
- return response
240
- }
241
- },
242
- }
243
- }
package/cli.ts DELETED
@@ -1,19 +0,0 @@
1
- #!/usr/bin/env node
2
- import { program, Option, Command } from 'commander'
3
- import { TradeStationClient } from 'tradestation-api-ts'
4
-
5
- import { authenticate, tryLoadAuth } from './authMiddleware.js'
6
- import type { BarUnit, SessionTemplate } from 'tradestation-api-ts/dist/types/marketData.js'
7
- import { authCommand } from './commands/auth.js'
8
- import { barsCommand } from './commands/barsCommand.js'
9
-
10
- program
11
- .addOption(
12
- new Option('--environment <environment>', 'TradeStation environment')
13
- .choices(['Live', 'Simulation'])
14
- .default('Simulation')
15
- )
16
- .addCommand(authCommand, { isDefault: true })
17
- .addCommand(barsCommand)
18
-
19
- await program.parseAsync()
package/commands/auth.ts DELETED
@@ -1,13 +0,0 @@
1
- import { Command } from 'commander'
2
-
3
- import { authenticate } from '../authMiddleware.js'
4
-
5
- export const authCommand = new Command('auth')
6
- .description('Authenticate with TradeStation API')
7
- .requiredOption('--clientId <clientId>', 'TradeStation Client ID')
8
- .requiredOption('--clientSecret <clientSecret>', 'TradeStation Client Secret')
9
- .action(async (options: { clientId: string; clientSecret: string }) => {
10
- console.log('Authenticating with TradeStation API...', options)
11
- await authenticate(options.clientId, options.clientSecret)
12
- console.log('Authentication successful!')
13
- })
@@ -1,88 +0,0 @@
1
- import { Command, Option } from 'commander'
2
- import { TradeStationClient } from 'tradestation-api-ts'
3
- import type { BarUnit, SessionTemplate } from 'tradestation-api-ts/dist/types/marketData.js'
4
- import fsp from 'fs/promises'
5
-
6
- import { tryLoadAuth } from '../authMiddleware.js'
7
-
8
- const sessions = ['Default', 'USEQPre', 'USEQPost', 'USEQPreAndPost', 'USEQ24Hour']
9
-
10
- const units = ['Minute', 'Hour', 'Daily', 'Weekly', 'Monthly']
11
-
12
- async function authenticateOrFail() {
13
- const authData = await tryLoadAuth()
14
- if (!authData) {
15
- console.error('No authentication data found. Please run the auth command first or provide credentials.')
16
- process.exit(1)
17
- }
18
- return authData
19
- }
20
-
21
- export const barsCommand = new Command('bars')
22
- .description('Download market data bars from TradeStation API')
23
- .argument('<symbol>', 'Market symbol to download data for')
24
- .option('--interval <interval>', 'Bar interval (e.g., 1, 5, 1440, ...)', '1')
25
- .addOption(new Option('--unit <unit>', 'Bar unit').choices(units).default('Daily'))
26
- .option('--barsBack <barsBack>', 'Number of bars to retrieve', parseInt)
27
- .option('--firstDate <firstDate>', 'First date for bar data (YYYY-MM-DD)')
28
- .option('--lastDate <lastDate>', 'Last date for bar data (YYYY-MM-DD)')
29
- .addOption(
30
- new Option('--sessionTemplate <sessionTemplate>', 'Session template to use.').choices(sessions).default(sessions[0])
31
- )
32
- // Optional authentication options
33
- .addOption(new Option('--clientId <clientId>', 'TradeStation Client ID'))
34
- .addOption(new Option('--clientSecret <clientSecret>', 'TradeStation Client Secret'))
35
- .addOption(new Option('--refreshToken <refreshToken>', 'TradeStation Refresh Token'))
36
- // Output options
37
- .option('-o --output <output>', 'Output file name, defaults to <symbol>.json')
38
- .action(async function (
39
- symbol: string,
40
- options: {
41
- interval: string
42
- unit: BarUnit
43
- barsBack: number
44
- firstDate: string
45
- lastDate: string
46
- sessionTemplate: SessionTemplate
47
- clientId?: string
48
- clientSecret?: string
49
- refreshToken?: string
50
- output: string
51
- }
52
- ) {
53
- const environment = this.optsWithGlobals().environment as 'Live' | 'Simulation'
54
- const output = options.output || `${symbol}.json`
55
-
56
- let client: TradeStationClient
57
-
58
- if (options.clientId && options.clientSecret && options.refreshToken) {
59
- client = new TradeStationClient({
60
- clientId: options.clientId,
61
- clientSecret: options.clientSecret,
62
- refresh_token: options.refreshToken,
63
- environment,
64
- })
65
- } else {
66
- const authData = await authenticateOrFail()
67
- client = new TradeStationClient({
68
- clientId: authData.client_id,
69
- clientSecret: authData.client_secret,
70
- refresh_token: authData.refresh_token,
71
- environment,
72
- })
73
- }
74
-
75
- console.log(`Downloading market data for symbol: ${symbol}`)
76
-
77
- const bars = await client.marketData.getBarHistory(symbol, {
78
- interval: options.interval,
79
- unit: options.unit,
80
- firstdate: options.firstDate,
81
- lastdate: options.lastDate,
82
- barsback: options.barsBack,
83
- sessiontemplate: options.sessionTemplate,
84
- })
85
-
86
- await fsp.writeFile(output, JSON.stringify(bars.Bars, null, 2))
87
- console.log(`Saved ${bars.Bars.length} bars to ${output}`)
88
- })
package/config.ts DELETED
@@ -1,2 +0,0 @@
1
- export const redirectPort = 31022
2
- export const redirectUri = `http://localhost:${redirectPort}`
package/dist/config.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export declare const redirectPort = 31022;
2
- export declare const redirectUri = "http://localhost:31022";
3
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,QAAQ,CAAA;AACjC,eAAO,MAAM,WAAW,2BAAqC,CAAA"}
package/dist/config.js DELETED
@@ -1,3 +0,0 @@
1
- export const redirectPort = 31022;
2
- export const redirectUri = `http://localhost:${redirectPort}`;
3
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,YAAY,GAAG,KAAK,CAAA;AACjC,MAAM,CAAC,MAAM,WAAW,GAAG,oBAAoB,YAAY,EAAE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"downloadOpenAPI.d.ts","sourceRoot":"","sources":["../downloadOpenAPI.ts"],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"downloadOpenAPI.js","sourceRoot":"","sources":["../downloadOpenAPI.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAE1C,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC;IACpC,QAAQ,EAAE,IAAI;IACd,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,CAAC,sBAAsB,CAAC;CAC/B,CAAC,CAAA;AACF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAA;AAEpC,MAAM,IAAI,CAAC,IAAI,CAAC,kDAAkD,CAAC,CAAA;AAEnE,MAAM,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,CAAA;AAE1C,MAAM,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,CAAA;AAErD,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,CAAA;AAE1D,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAA;AACtC,MAAM,cAAc,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;AAE5C,IAAI,cAAc,EAAE,CAAC;IACnB,MAAM,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC,CAAA;IACnE,MAAM,MAAM,CAAC,cAAc,CAAC,CAAA;IAC5B,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;AAC1D,CAAC;KAAM,CAAC;IACN,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;AACpC,CAAC;AAED,MAAM,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tradestation-client.d.ts","sourceRoot":"","sources":["../tradestation-client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iCAAiC,CAAA;AAG5D,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,gEAOrB"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"tradestation-client.js","sourceRoot":"","sources":["../tradestation-client.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,eAAe,CAAA;AAGxC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAE1D,MAAM,UAAU,wBAAwB,CACtC,QAAgB,EAChB,YAAoB;IAEpB,MAAM,MAAM,GAAG,YAAY,CAAQ;QACjC,OAAO,EAAE,8BAA8B;KACxC,CAAC,CAAA;IACF,MAAM,CAAC,GAAG,CAAC,oBAAoB,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC,CAAA;IACxD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -1,31 +0,0 @@
1
- import { copyFile, unlink } from 'node:fs/promises'
2
- import { join } from 'node:path'
3
- import { chromium } from 'playwright-core'
4
-
5
- const browser = await chromium.launch({
6
- headless: true,
7
- channel: 'chrome',
8
- args: ['--disable-extensions'],
9
- })
10
- const page = await browser.newPage()
11
-
12
- await page.goto('https://api.tradestation.com/docs/specification/')
13
-
14
- await page.waitForLoadState('networkidle')
15
-
16
- const downloadPromise = page.waitForEvent('download')
17
-
18
- await page.getByRole('link', { name: 'Download' }).click()
19
-
20
- const download = await downloadPromise
21
- const downloadedPath = await download.path()
22
-
23
- if (downloadedPath) {
24
- await copyFile(downloadedPath, join(process.cwd(), 'openapi.json'))
25
- await unlink(downloadedPath)
26
- console.log('✅ OpenAPI spec downloaded to openapi.json')
27
- } else {
28
- throw new Error('Download failed')
29
- }
30
-
31
- await browser.close()