@tastytrade/api 0.0.1 → 1.0.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/.env CHANGED
@@ -1,5 +1,5 @@
1
- BASE_URL=https://api.tastyworks.com
2
- API_USERNAME=dmoss18
1
+ BASE_URL=https://api.cert.tastyworks.com
2
+ API_USERNAME=devin.moss@tastytrade.com
3
3
  API_PASSWORD=rebuke-padding-vizor
4
- API_CUSTOMER_ID=me
5
- API_ACCOUNT_NUMBER=5WT05020
4
+ API_ACCOUNT_NUMBER=5WT05179
5
+ API_CUSTOMER_ID=31
@@ -7,18 +7,14 @@
7
7
  {
8
8
  "type": "node",
9
9
  "request": "launch",
10
- "name": "Integration Tests",
11
- "skipFiles": ["<node_internals>/**"],
10
+ "name": "Launch Program",
11
+ "skipFiles": [
12
+ "<node_internals>/**"
13
+ ],
12
14
  "program": "${workspaceFolder}/node_modules/jest/bin/jest.js",
13
- "args": ["-i", "--", "tests/integration/service/instruments-service.test.ts"]
14
- },
15
- {
16
- "type": "node",
17
- "request": "launch",
18
- "name": "Unit Tests",
19
- "skipFiles": ["<node_internals>/**"],
20
- "program": "${workspaceFolder}/node_modules/jest/bin/jest.js",
21
- "args": ["-i", "--", "tests/unit/service/session-service.test.ts"]
15
+ "args": [
16
+ "-c", "jest.config.js", "tests/integration/service/accounts-and-customers-service.test.ts"
17
+ ]
22
18
  }
23
19
  ]
24
20
  }
package/README.md CHANGED
@@ -1,4 +1,80 @@
1
1
  # Tastytrade Api Javascript SDK
2
+
3
+ ## Installation
4
+ npm:
5
+ `npm -i @tastytrade/api`
6
+
7
+ yarn:
8
+ `yarn add @tastytrade/api`
9
+
10
+ ## Quickstart
11
+ ```js
12
+ import TastytradeClient from "@tastytrade/api"
13
+ const tastytradeClient = new TastytradeClient(baseUrl, accountStreamerUrl)
14
+ const loginResponse = await tastytradeClient.sessionService.login(usernameOrEmail, pasword)
15
+ const accounts = await tastytradeClient.accountsAndCustomersService.getCustomerAccounts()
16
+ const accountPositions = await tastytradeClient.balancesAndPositionsService.getPositionsList(accounts[0].accounts['account-number'])
17
+ ```
18
+
19
+ ### Market Data
20
+ ```js
21
+ import TastytradeClient, { QuoteStreamer } from "@tastytrade-api"
22
+ const tastytradeClient = new TastytradeClient(baseUrl, accountStreamerUrl)
23
+ await tastytradeClient.sessionService.login(usernameOrEmail, pasword)
24
+ const tokenResponse = await tastytradeClient.AccountsAndCustomersService.getQuoteStreamerTokens()
25
+ const quoteStreamer = new QuoteStreamer(tokenResponse.token, `${tokenResponse['websocket-url']}/cometd`)
26
+ quoteStreamer.connect()
27
+
28
+ function handleMarketDataReceived(event) {
29
+ // Triggers every time market data event occurs
30
+ console.log(event)
31
+ }
32
+ // Subscribe to a single equity quote
33
+ quoteStreamer.subscribe('AAPL', handleMarketDataReceived)
34
+
35
+ // Subscribe to a single equity option quote
36
+ const optionChain = await tastytradeClient.instrumentsService.getOptionChain('AAPL')
37
+ quoteStreamer.subscribe(optionChain[0]['streamer-symbol'], handleMarketDataReceived)
38
+ ```
39
+
40
+ ### Account Streamer
41
+ ```js
42
+ const TastytradeApi = require("@tastytrade/api")
43
+ const TastytradeClient = TastytradeApi.default
44
+ const { AccountStreamer, QuoteStreamer } = TastytradeApi
45
+ const _ = require('lodash')
46
+
47
+ function handleStreamerMessage(json) {
48
+ console.log('streamer message received: ', json)
49
+ }
50
+
51
+ function handleStreamerStateChange(streamerState) {
52
+ console.log('streamer state changed: ', streamerState)
53
+ }
54
+
55
+ const tastytradeClient = new TastytradeClient(baseUrl, accountStreamerUrl)
56
+ const accountStreamer = tastytradeClient.accountStreamer
57
+ const loginResponse = await tastytradeClient.sessionService.login(usernameOrEmail, password)
58
+ const accounts = await tastytradeClient.accountsAndCustomersService.getCustomerAccounts()
59
+ const accountNumbers = _.map(accounts, account => _.get(account, 'account.account-number'))
60
+ await accountStreamer.start()
61
+ await accountStreamer.subscribeToAccounts(accountNumbers)
62
+ accountStreamer.addMessageObserver(handleStreamerMessage)
63
+ accountStreamer.addStreamerStateObserver(handleStreamerStateChange)
64
+ ```
65
+
66
+ You should then be able to place a trade and see live status updates for the order come through via `handleStreamerMessage`.
67
+
68
+ ## Running in Node
69
+ The `cometd` package has an explicit reference to `window`, so there's not a perfect way to run this code in a NodeJs. You could fake the `window` object to get it running. You'll have to `npm install ws` and do this:
70
+
71
+ ```js
72
+ const WebSocket = require('ws')
73
+
74
+ global.WebSocket = WebSocket
75
+ global.window = { WebSocket, setTimeout, clearTimeout }
76
+ ```
77
+
2
78
  ## Building Locally
3
79
  `npm run build`
4
80
  Outputs everything to `dist/`
@@ -8,7 +8,7 @@ export declare enum STREAMER_STATE {
8
8
  }
9
9
  export declare type Disposer = () => void;
10
10
  export declare type StreamerStateObserver = (streamerState: STREAMER_STATE) => void;
11
- export declare type StreamerMessageObserver = (messageType: string, action: string, status: string) => void;
11
+ export declare type StreamerMessageObserver = (json: object) => void;
12
12
  export declare class AccountStreamer {
13
13
  private readonly url;
14
14
  private readonly session;
@@ -143,7 +143,7 @@ var AccountStreamer = /** @class */ (function () {
143
143
  this.handleOneMessage = function (json) {
144
144
  _this.logger.info(json);
145
145
  var action = json.action;
146
- _this.streamerMessageObservers.forEach(function (observer) { return observer(json.type, action, json.status); });
146
+ _this.streamerMessageObservers.forEach(function (observer) { return observer(json); });
147
147
  if (action) {
148
148
  if (action === MessageAction.HEARTBEAT) {
149
149
  // schedule next heartbeat
@@ -3,8 +3,8 @@ export default class AccountsAndCustomersService {
3
3
  private httpClient;
4
4
  constructor(httpClient: TastytradeHttpClient);
5
5
  getCustomerAccounts(): Promise<any>;
6
- getCustomerResource(customerId: string): Promise<any>;
7
- getCustomerAccountResources(customerId: string): Promise<any>;
8
- getFullCustomerAccountResource(customerId: string, accountNumber: string): Promise<any>;
6
+ getCustomerResource(): Promise<any>;
7
+ getCustomerAccountResources(): Promise<any>;
8
+ getFullCustomerAccountResource(accountNumber: string): Promise<any>;
9
9
  getQuoteStreamerTokens(): Promise<any>;
10
10
  }
@@ -58,12 +58,12 @@ var AccountsAndCustomersService = /** @class */ (function () {
58
58
  });
59
59
  };
60
60
  //Customers: Operations about customers
61
- AccountsAndCustomersService.prototype.getCustomerResource = function (customerId) {
61
+ AccountsAndCustomersService.prototype.getCustomerResource = function () {
62
62
  return __awaiter(this, void 0, void 0, function () {
63
63
  var customerResource;
64
64
  return __generator(this, function (_a) {
65
65
  switch (_a.label) {
66
- case 0: return [4 /*yield*/, this.httpClient.getData("/customers/".concat(customerId), {}, {})];
66
+ case 0: return [4 /*yield*/, this.httpClient.getData("/customers/me", {}, {})];
67
67
  case 1:
68
68
  customerResource = (_a.sent());
69
69
  return [2 /*return*/, (0, response_util_1.default)(customerResource)];
@@ -71,12 +71,12 @@ var AccountsAndCustomersService = /** @class */ (function () {
71
71
  });
72
72
  });
73
73
  };
74
- AccountsAndCustomersService.prototype.getCustomerAccountResources = function (customerId) {
74
+ AccountsAndCustomersService.prototype.getCustomerAccountResources = function () {
75
75
  return __awaiter(this, void 0, void 0, function () {
76
76
  var customerAccountResources;
77
77
  return __generator(this, function (_a) {
78
78
  switch (_a.label) {
79
- case 0: return [4 /*yield*/, this.httpClient.getData("/customers/".concat(customerId, "/accounts"), {}, {})];
79
+ case 0: return [4 /*yield*/, this.httpClient.getData("/customers/me/accounts", {}, {})];
80
80
  case 1:
81
81
  customerAccountResources = (_a.sent());
82
82
  return [2 /*return*/, (0, response_util_1.default)(customerAccountResources)];
@@ -84,12 +84,12 @@ var AccountsAndCustomersService = /** @class */ (function () {
84
84
  });
85
85
  });
86
86
  };
87
- AccountsAndCustomersService.prototype.getFullCustomerAccountResource = function (customerId, accountNumber) {
87
+ AccountsAndCustomersService.prototype.getFullCustomerAccountResource = function (accountNumber) {
88
88
  return __awaiter(this, void 0, void 0, function () {
89
89
  var fullCustomerAccountResource;
90
90
  return __generator(this, function (_a) {
91
91
  switch (_a.label) {
92
- case 0: return [4 /*yield*/, this.httpClient.getData("/customers/".concat(customerId, "/accounts/").concat(accountNumber), {}, {})];
92
+ case 0: return [4 /*yield*/, this.httpClient.getData("/customers/me/accounts/".concat(accountNumber), {}, {})];
93
93
  case 1:
94
94
  fullCustomerAccountResource = (_a.sent());
95
95
  return [2 /*return*/, (0, response_util_1.default)(fullCustomerAccountResource)];
@@ -26,7 +26,7 @@ export type Disposer = () => void
26
26
 
27
27
  export type StreamerStateObserver = (streamerState: STREAMER_STATE) => void
28
28
 
29
- export type StreamerMessageObserver = (messageType: string, action: string, status: string) => void
29
+ export type StreamerMessageObserver = (json: object) => void
30
30
 
31
31
  const REQUEST_ID = 'request-id'
32
32
 
@@ -368,7 +368,7 @@ export class AccountStreamer {
368
368
  this.logger.info(json)
369
369
 
370
370
  const action = json.action as string
371
- this.streamerMessageObservers.forEach(observer => observer(json.type as string, action, json.status as string))
371
+ this.streamerMessageObservers.forEach(observer => observer(json))
372
372
  if (action) {
373
373
  if (action === MessageAction.HEARTBEAT) {
374
374
  // schedule next heartbeat
@@ -10,19 +10,19 @@ export default class AccountsAndCustomersService {
10
10
  }
11
11
 
12
12
  //Customers: Operations about customers
13
- async getCustomerResource(customerId: string){
13
+ async getCustomerResource(){
14
14
  //Get a full customer resource.
15
- const customerResource = (await this.httpClient.getData(`/customers/${customerId}`, {}, {}))
15
+ const customerResource = (await this.httpClient.getData(`/customers/me`, {}, {}))
16
16
  return extractResponseData(customerResource)
17
17
  }
18
- async getCustomerAccountResources(customerId: string){
18
+ async getCustomerAccountResources(){
19
19
  //Get a list of all the customer account resources attached to the current customer.
20
- const customerAccountResources = (await this.httpClient.getData(`/customers/${customerId}/accounts`, {}, {}))
20
+ const customerAccountResources = (await this.httpClient.getData(`/customers/me/accounts`, {}, {}))
21
21
  return extractResponseData(customerAccountResources)
22
22
  }
23
- async getFullCustomerAccountResource(customerId: string, accountNumber: string){
23
+ async getFullCustomerAccountResource(accountNumber: string){
24
24
  //Get a full customer account resource.
25
- const fullCustomerAccountResource = (await this.httpClient.getData(`/customers/${customerId}/accounts/${accountNumber}`, {}, {}))
25
+ const fullCustomerAccountResource = (await this.httpClient.getData(`/customers/me/accounts/${accountNumber}`, {}, {}))
26
26
  return extractResponseData(fullCustomerAccountResource)
27
27
  }
28
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tastytrade/api",
3
- "version": "0.0.1",
3
+ "version": "1.0.0",
4
4
  "main": "dist/tastytrade-api.js",
5
5
  "typings": "dist/tastytrade-api.d.ts",
6
6
  "repository": "https://github.com/tastytrade/tastytrade-api-js",