tradestation-client 1.0.15 → 1.1.0
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.
- package/.prettierrc +2 -1
- package/commands/barsCommand.ts +10 -5
- package/dist/commands/barsCommand.d.ts.map +1 -1
- package/dist/commands/barsCommand.js +9 -5
- package/dist/commands/barsCommand.js.map +1 -1
- package/dist/test/cli.test.d.ts +2 -0
- package/dist/test/cli.test.d.ts.map +1 -0
- package/dist/test/cli.test.js +32 -0
- package/dist/test/cli.test.js.map +1 -0
- package/package.json +4 -1
- package/test/cli.test.ts +37 -0
package/.prettierrc
CHANGED
package/commands/barsCommand.ts
CHANGED
|
@@ -12,7 +12,7 @@ const units = ['Minute', 'Hour', 'Daily', 'Weekly', 'Monthly']
|
|
|
12
12
|
async function authenticateOrFail() {
|
|
13
13
|
const authData = await tryLoadAuth()
|
|
14
14
|
if (!authData) {
|
|
15
|
-
console.error('No authentication data found. Please run the auth command first.')
|
|
15
|
+
console.error('No authentication data found. Please run the auth command first or provide credentials.')
|
|
16
16
|
process.exit(1)
|
|
17
17
|
}
|
|
18
18
|
return authData
|
|
@@ -22,16 +22,19 @@ export const barsCommand = new Command('bars')
|
|
|
22
22
|
.description('Download market data bars from TradeStation API')
|
|
23
23
|
.argument('<symbol>', 'Market symbol to download data for')
|
|
24
24
|
.option('--interval <interval>', 'Bar interval (e.g., 1, 5, 1440, ...)', '1')
|
|
25
|
-
.addOption(new Option('--unit <unit>', 'Bar unit').choices(units).default(
|
|
26
|
-
.option('--barsBack <barsBack>', 'Number of bars to retrieve', parseInt
|
|
25
|
+
.addOption(new Option('--unit <unit>', 'Bar unit').choices(units).default('Daily'))
|
|
26
|
+
.option('--barsBack <barsBack>', 'Number of bars to retrieve', parseInt)
|
|
27
27
|
.option('--firstDate <firstDate>', 'First date for bar data (YYYY-MM-DD)')
|
|
28
28
|
.option('--lastDate <lastDate>', 'Last date for bar data (YYYY-MM-DD)')
|
|
29
29
|
.addOption(
|
|
30
30
|
new Option('--sessionTemplate <sessionTemplate>', 'Session template to use.').choices(sessions).default(sessions[0])
|
|
31
31
|
)
|
|
32
|
+
// Optional authentication options
|
|
32
33
|
.addOption(new Option('--clientId <clientId>', 'TradeStation Client ID'))
|
|
33
34
|
.addOption(new Option('--clientSecret <clientSecret>', 'TradeStation Client Secret'))
|
|
34
35
|
.addOption(new Option('--refreshToken <refreshToken>', 'TradeStation Refresh Token'))
|
|
36
|
+
// Output options
|
|
37
|
+
.option('-o --output <output>', 'Output file name, defaults to <symbol>.json')
|
|
35
38
|
.action(async function (
|
|
36
39
|
symbol: string,
|
|
37
40
|
options: {
|
|
@@ -44,9 +47,11 @@ export const barsCommand = new Command('bars')
|
|
|
44
47
|
clientId?: string
|
|
45
48
|
clientSecret?: string
|
|
46
49
|
refreshToken?: string
|
|
50
|
+
output: string
|
|
47
51
|
}
|
|
48
52
|
) {
|
|
49
53
|
const environment = this.optsWithGlobals().environment as 'Live' | 'Simulation'
|
|
54
|
+
const output = options.output || `${symbol}.json`
|
|
50
55
|
|
|
51
56
|
let client: TradeStationClient
|
|
52
57
|
|
|
@@ -78,6 +83,6 @@ export const barsCommand = new Command('bars')
|
|
|
78
83
|
sessiontemplate: options.sessionTemplate,
|
|
79
84
|
})
|
|
80
85
|
|
|
81
|
-
await fsp.writeFile(
|
|
82
|
-
console.log(`Saved ${bars.Bars.length} bars to ${
|
|
86
|
+
await fsp.writeFile(output, JSON.stringify(bars.Bars, null, 2))
|
|
87
|
+
console.log(`Saved ${bars.Bars.length} bars to ${output}`)
|
|
83
88
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"barsCommand.d.ts","sourceRoot":"","sources":["../../commands/barsCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAoB3C,eAAO,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"barsCommand.d.ts","sourceRoot":"","sources":["../../commands/barsCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAU,MAAM,WAAW,CAAA;AAoB3C,eAAO,MAAM,WAAW,SAmEpB,CAAA"}
|
|
@@ -7,7 +7,7 @@ const units = ['Minute', 'Hour', 'Daily', 'Weekly', 'Monthly'];
|
|
|
7
7
|
async function authenticateOrFail() {
|
|
8
8
|
const authData = await tryLoadAuth();
|
|
9
9
|
if (!authData) {
|
|
10
|
-
console.error('No authentication data found. Please run the auth command first.');
|
|
10
|
+
console.error('No authentication data found. Please run the auth command first or provide credentials.');
|
|
11
11
|
process.exit(1);
|
|
12
12
|
}
|
|
13
13
|
return authData;
|
|
@@ -16,16 +16,20 @@ export const barsCommand = new Command('bars')
|
|
|
16
16
|
.description('Download market data bars from TradeStation API')
|
|
17
17
|
.argument('<symbol>', 'Market symbol to download data for')
|
|
18
18
|
.option('--interval <interval>', 'Bar interval (e.g., 1, 5, 1440, ...)', '1')
|
|
19
|
-
.addOption(new Option('--unit <unit>', 'Bar unit').choices(units).default(
|
|
20
|
-
.option('--barsBack <barsBack>', 'Number of bars to retrieve', parseInt
|
|
19
|
+
.addOption(new Option('--unit <unit>', 'Bar unit').choices(units).default('Daily'))
|
|
20
|
+
.option('--barsBack <barsBack>', 'Number of bars to retrieve', parseInt)
|
|
21
21
|
.option('--firstDate <firstDate>', 'First date for bar data (YYYY-MM-DD)')
|
|
22
22
|
.option('--lastDate <lastDate>', 'Last date for bar data (YYYY-MM-DD)')
|
|
23
23
|
.addOption(new Option('--sessionTemplate <sessionTemplate>', 'Session template to use.').choices(sessions).default(sessions[0]))
|
|
24
|
+
// Optional authentication options
|
|
24
25
|
.addOption(new Option('--clientId <clientId>', 'TradeStation Client ID'))
|
|
25
26
|
.addOption(new Option('--clientSecret <clientSecret>', 'TradeStation Client Secret'))
|
|
26
27
|
.addOption(new Option('--refreshToken <refreshToken>', 'TradeStation Refresh Token'))
|
|
28
|
+
// Output options
|
|
29
|
+
.option('-o --output <output>', 'Output file name, defaults to <symbol>.json')
|
|
27
30
|
.action(async function (symbol, options) {
|
|
28
31
|
const environment = this.optsWithGlobals().environment;
|
|
32
|
+
const output = options.output || `${symbol}.json`;
|
|
29
33
|
let client;
|
|
30
34
|
if (options.clientId && options.clientSecret && options.refreshToken) {
|
|
31
35
|
client = new TradeStationClient({
|
|
@@ -53,7 +57,7 @@ export const barsCommand = new Command('bars')
|
|
|
53
57
|
barsback: options.barsBack,
|
|
54
58
|
sessiontemplate: options.sessionTemplate,
|
|
55
59
|
});
|
|
56
|
-
await fsp.writeFile(
|
|
57
|
-
console.log(`Saved ${bars.Bars.length} bars to ${
|
|
60
|
+
await fsp.writeFile(output, JSON.stringify(bars.Bars, null, 2));
|
|
61
|
+
console.log(`Saved ${bars.Bars.length} bars to ${output}`);
|
|
58
62
|
});
|
|
59
63
|
//# sourceMappingURL=barsCommand.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"barsCommand.js","sourceRoot":"","sources":["../../commands/barsCommand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AAExD,OAAO,GAAG,MAAM,aAAa,CAAA;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAA;AAElD,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,CAAC,CAAA;AAEnF,MAAM,KAAK,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAA;AAE9D,KAAK,UAAU,kBAAkB;IAC/B,MAAM,QAAQ,GAAG,MAAM,WAAW,EAAE,CAAA;IACpC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"barsCommand.js","sourceRoot":"","sources":["../../commands/barsCommand.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.d.ts","sourceRoot":"","sources":["../../test/cli.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, test, beforeEach, mock } from 'node:test';
|
|
2
|
+
describe('CLI Tests', () => {
|
|
3
|
+
describe('auth command', () => {
|
|
4
|
+
beforeEach(t => {
|
|
5
|
+
mock.reset();
|
|
6
|
+
mock.module('../authMiddleware.js', {
|
|
7
|
+
namedExports: {
|
|
8
|
+
authenticate: mock.fn(),
|
|
9
|
+
},
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
test('should require clientId and clientSecret', async (t) => {
|
|
13
|
+
const { authCommand } = await import('../commands/auth.js');
|
|
14
|
+
t.assert.throws(() => authCommand.exitOverride().parse([], { from: 'user' }));
|
|
15
|
+
});
|
|
16
|
+
test('should fail with just clientId', async (t) => {
|
|
17
|
+
const { authCommand } = await import('../commands/auth.js');
|
|
18
|
+
t.assert.throws(() => authCommand.exitOverride().parse(['--clientId', 'myClientId'], { from: 'user' }));
|
|
19
|
+
});
|
|
20
|
+
test('should fail with just clientSecret', async (t) => {
|
|
21
|
+
const { authCommand } = await import('../commands/auth.js');
|
|
22
|
+
t.assert.throws(() => authCommand.exitOverride().parse(['--clientSecret', 'myClientSecret'], { from: 'user' }));
|
|
23
|
+
});
|
|
24
|
+
test('should pass with both clientId and clientSecret', async (t) => {
|
|
25
|
+
const { authCommand } = await import('../commands/auth.js');
|
|
26
|
+
authCommand.exitOverride().parse(['--clientId', 'myClientId', '--clientSecret', 'myClientSecret'], {
|
|
27
|
+
from: 'user',
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=cli.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.test.js","sourceRoot":"","sources":["../../test/cli.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAE5D,QAAQ,CAAC,WAAW,EAAE,GAAG,EAAE;IACzB,QAAQ,CAAC,cAAc,EAAE,GAAG,EAAE;QAC5B,UAAU,CAAC,CAAC,CAAC,EAAE;YACb,IAAI,CAAC,KAAK,EAAE,CAAA;YACZ,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE;gBAClC,YAAY,EAAE;oBACZ,YAAY,EAAE,IAAI,CAAC,EAAE,EAAE;iBACxB;aACF,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,0CAA0C,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;YACzD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;YAC3D,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAC/E,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,gCAAgC,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;YAC/C,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;YAC3D,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,YAAY,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QACzG,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,oCAAoC,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;YACnD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;YAC3D,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QACjH,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,iDAAiD,EAAE,KAAK,EAAC,CAAC,EAAC,EAAE;YAChE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAA;YAE3D,WAAW,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,CAAC,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,CAAC,EAAE;gBACjG,IAAI,EAAE,MAAM;aACb,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tradestation-client",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A Node.js client for the TradeStation API with OAuth2 authentication and OpenAPI integration.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": "./dist/cli.js",
|
|
7
7
|
"scripts": {
|
|
8
|
+
"test": "tsx --experimental-test-module-mocks --test",
|
|
8
9
|
"test:ts": "tsc --noEmit",
|
|
10
|
+
"cli": "tsx cli.ts",
|
|
9
11
|
"download-openapi": "node ./downloadOpenAPI.ts",
|
|
10
12
|
"generate-client": "openapi-typescript ./openapi.json --output generated/tradestation-api.d.ts",
|
|
11
13
|
"build": "npm run download-openapi && npm run generate-client && tsc",
|
|
@@ -26,6 +28,7 @@
|
|
|
26
28
|
"@types/node": "^25.0.3",
|
|
27
29
|
"openapi-typescript": "^7.10.1",
|
|
28
30
|
"playwright-core": "^1.57.0",
|
|
31
|
+
"tsx": "^4.21.0",
|
|
29
32
|
"typescript": "^5.9.3"
|
|
30
33
|
}
|
|
31
34
|
}
|
package/test/cli.test.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, test, beforeEach, mock } from 'node:test'
|
|
2
|
+
|
|
3
|
+
describe('CLI Tests', () => {
|
|
4
|
+
describe('auth command', () => {
|
|
5
|
+
beforeEach(t => {
|
|
6
|
+
mock.reset()
|
|
7
|
+
mock.module('../authMiddleware.js', {
|
|
8
|
+
namedExports: {
|
|
9
|
+
authenticate: mock.fn(),
|
|
10
|
+
},
|
|
11
|
+
})
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test('should require clientId and clientSecret', async t => {
|
|
15
|
+
const { authCommand } = await import('../commands/auth.js')
|
|
16
|
+
t.assert.throws(() => authCommand.exitOverride().parse([], { from: 'user' }))
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
test('should fail with just clientId', async t => {
|
|
20
|
+
const { authCommand } = await import('../commands/auth.js')
|
|
21
|
+
t.assert.throws(() => authCommand.exitOverride().parse(['--clientId', 'myClientId'], { from: 'user' }))
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
test('should fail with just clientSecret', async t => {
|
|
25
|
+
const { authCommand } = await import('../commands/auth.js')
|
|
26
|
+
t.assert.throws(() => authCommand.exitOverride().parse(['--clientSecret', 'myClientSecret'], { from: 'user' }))
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
test('should pass with both clientId and clientSecret', async t => {
|
|
30
|
+
const { authCommand } = await import('../commands/auth.js')
|
|
31
|
+
|
|
32
|
+
authCommand.exitOverride().parse(['--clientId', 'myClientId', '--clientSecret', 'myClientSecret'], {
|
|
33
|
+
from: 'user',
|
|
34
|
+
})
|
|
35
|
+
})
|
|
36
|
+
})
|
|
37
|
+
})
|