@tastytrade/api 2.1.2 → 3.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/dist/account-streamer.js +5 -1
- package/dist/market-data-streamer.js +5 -2
- package/dist/services/account-status-service.js +1 -1
- package/dist/services/orders-service.d.ts +2 -0
- package/dist/services/orders-service.js +26 -0
- package/dist/services/tastytrade-http-client.d.ts +1 -0
- package/dist/services/tastytrade-http-client.js +6 -1
- package/dist/utils/constants.d.ts +1 -0
- package/dist/utils/constants.js +4 -0
- package/lib/account-streamer.ts +9 -5
- package/lib/market-data-streamer.ts +7 -4
- package/lib/services/account-status-service.ts +1 -1
- package/lib/services/orders-service.ts +12 -0
- package/lib/services/tastytrade-http-client.ts +7 -1
- package/lib/utils/constants.ts +1 -0
- package/package.json +9 -3
package/dist/account-streamer.js
CHANGED
|
@@ -43,6 +43,7 @@ exports.AccountStreamer = exports.STREAMER_STATE = void 0;
|
|
|
43
43
|
var isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
|
|
44
44
|
var lodash_1 = __importDefault(require("lodash"));
|
|
45
45
|
var json_util_1 = require("./utils/json-util");
|
|
46
|
+
var constants_1 = require("./utils/constants");
|
|
46
47
|
var STREAMER_STATE;
|
|
47
48
|
(function (STREAMER_STATE) {
|
|
48
49
|
STREAMER_STATE[STREAMER_STATE["Open"] = 0] = "Open";
|
|
@@ -231,7 +232,10 @@ var AccountStreamer = /** @class */ (function () {
|
|
|
231
232
|
if (this.startPromise !== null) {
|
|
232
233
|
return [2 /*return*/, this.startPromise];
|
|
233
234
|
}
|
|
234
|
-
|
|
235
|
+
this.websocket = new isomorphic_ws_1.default(this.url, [], {
|
|
236
|
+
minVersion: constants_1.MinTlsVersion // TLS Config
|
|
237
|
+
});
|
|
238
|
+
websocket = this.websocket;
|
|
235
239
|
this.lastCloseEvent = null;
|
|
236
240
|
this.lastErrorEvent = null;
|
|
237
241
|
websocket.addEventListener('open', this.handleOpen);
|
|
@@ -7,6 +7,7 @@ exports.CandleType = exports.MarketDataSubscriptionType = void 0;
|
|
|
7
7
|
var isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
|
|
8
8
|
var lodash_1 = __importDefault(require("lodash"));
|
|
9
9
|
var uuid_1 = require("uuid");
|
|
10
|
+
var constants_1 = require("./utils/constants");
|
|
10
11
|
var MarketDataSubscriptionType;
|
|
11
12
|
(function (MarketDataSubscriptionType) {
|
|
12
13
|
MarketDataSubscriptionType["Candle"] = "Candle";
|
|
@@ -80,7 +81,9 @@ var MarketDataStreamer = /** @class */ (function () {
|
|
|
80
81
|
throw new Error('MarketDataStreamer is attempting to connect when an existing websocket is already connected');
|
|
81
82
|
}
|
|
82
83
|
this.token = token;
|
|
83
|
-
this.webSocket = new isomorphic_ws_1.default(url
|
|
84
|
+
this.webSocket = new isomorphic_ws_1.default(url, [], {
|
|
85
|
+
minVersion: constants_1.MinTlsVersion // TLS Config
|
|
86
|
+
});
|
|
84
87
|
this.webSocket.onopen = this.onOpen.bind(this);
|
|
85
88
|
this.webSocket.onerror = this.onError.bind(this);
|
|
86
89
|
this.webSocket.onmessage = this.handleMessageReceived.bind(this);
|
|
@@ -320,7 +323,7 @@ var MarketDataStreamer = /** @class */ (function () {
|
|
|
320
323
|
this.errorListeners.forEach(function (listener) { return listener(error); });
|
|
321
324
|
};
|
|
322
325
|
MarketDataStreamer.prototype.handleMessageReceived = function (data) {
|
|
323
|
-
var messageData = lodash_1.default.get(data, 'data',
|
|
326
|
+
var messageData = lodash_1.default.get(data, 'data', '{}');
|
|
324
327
|
var jsonData = JSON.parse(messageData);
|
|
325
328
|
switch (jsonData.type) {
|
|
326
329
|
case 'AUTH_STATE':
|
|
@@ -40,7 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
40
40
|
};
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
42
|
var response_util_1 = __importDefault(require("../utils/response-util"));
|
|
43
|
-
// create the central class that aggregates all services
|
|
43
|
+
// create the central class that aggregates all services
|
|
44
44
|
var AccountStatusService = /** @class */ (function () {
|
|
45
45
|
function AccountStatusService(httpClient) {
|
|
46
46
|
this.httpClient = httpClient;
|
|
@@ -6,11 +6,13 @@ export default class OrderService {
|
|
|
6
6
|
replacementOrderDryRun(accountNumber: string, orderId: number, replacementOrder: object): Promise<any>;
|
|
7
7
|
getOrder(accountNumber: string, orderId: number): Promise<any>;
|
|
8
8
|
cancelOrder(accountNumber: string, orderId: number): Promise<any>;
|
|
9
|
+
cancelComplexOrder(accountNumber: string, orderId: number): Promise<any>;
|
|
9
10
|
replaceOrder(accountNumber: string, orderId: number, replacementOrder: object): Promise<any>;
|
|
10
11
|
editOrder(accountNumber: string, orderId: number, order: object): Promise<any>;
|
|
11
12
|
getLiveOrders(accountNumber: string): Promise<any>;
|
|
12
13
|
getOrders(accountNumber: string, queryParams?: {}): Promise<any>;
|
|
13
14
|
createOrder(accountNumber: string, order: object): Promise<any>;
|
|
15
|
+
createComplexOrder(accountNumber: string, order: object): Promise<any>;
|
|
14
16
|
postOrderDryRun(accountNumber: string, order: object): Promise<any>;
|
|
15
17
|
getLiveOrdersForCustomer(customerId: string): Promise<any>;
|
|
16
18
|
getCustomerOrders(customerId: string, queryParams?: {}): Promise<any>;
|
|
@@ -97,6 +97,19 @@ var OrderService = /** @class */ (function () {
|
|
|
97
97
|
});
|
|
98
98
|
});
|
|
99
99
|
};
|
|
100
|
+
OrderService.prototype.cancelComplexOrder = function (accountNumber, orderId) {
|
|
101
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
102
|
+
var order;
|
|
103
|
+
return __generator(this, function (_a) {
|
|
104
|
+
switch (_a.label) {
|
|
105
|
+
case 0: return [4 /*yield*/, this.httpClient.deleteData("/accounts/".concat(accountNumber, "/complex-orders/").concat(orderId), {})];
|
|
106
|
+
case 1:
|
|
107
|
+
order = _a.sent();
|
|
108
|
+
return [2 /*return*/, (0, response_util_1.default)(order)];
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
};
|
|
100
113
|
OrderService.prototype.replaceOrder = function (accountNumber, orderId, replacementOrder) {
|
|
101
114
|
return __awaiter(this, void 0, void 0, function () {
|
|
102
115
|
var order;
|
|
@@ -163,6 +176,19 @@ var OrderService = /** @class */ (function () {
|
|
|
163
176
|
});
|
|
164
177
|
});
|
|
165
178
|
};
|
|
179
|
+
OrderService.prototype.createComplexOrder = function (accountNumber, order) {
|
|
180
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
181
|
+
var orderResponse;
|
|
182
|
+
return __generator(this, function (_a) {
|
|
183
|
+
switch (_a.label) {
|
|
184
|
+
case 0: return [4 /*yield*/, this.httpClient.postData("/accounts/".concat(accountNumber, "/complex-orders"), order, {})];
|
|
185
|
+
case 1:
|
|
186
|
+
orderResponse = _a.sent();
|
|
187
|
+
return [2 /*return*/, (0, response_util_1.default)(orderResponse)];
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
};
|
|
166
192
|
OrderService.prototype.postOrderDryRun = function (accountNumber, order) {
|
|
167
193
|
return __awaiter(this, void 0, void 0, function () {
|
|
168
194
|
var orderDryRun;
|
|
@@ -2,6 +2,7 @@ import TastytradeSession from "../models/tastytrade-session";
|
|
|
2
2
|
export default class TastytradeHttpClient {
|
|
3
3
|
private readonly baseUrl;
|
|
4
4
|
readonly session: TastytradeSession;
|
|
5
|
+
private readonly httpsAgent;
|
|
5
6
|
constructor(baseUrl: string);
|
|
6
7
|
private getDefaultHeaders;
|
|
7
8
|
private executeRequest;
|
|
@@ -55,6 +55,8 @@ var axios_1 = __importDefault(require("axios"));
|
|
|
55
55
|
var qs_1 = __importDefault(require("qs"));
|
|
56
56
|
var json_util_1 = require("../utils/json-util");
|
|
57
57
|
var lodash_1 = __importDefault(require("lodash"));
|
|
58
|
+
var https_1 = __importDefault(require("https"));
|
|
59
|
+
var constants_1 = require("../utils/constants");
|
|
58
60
|
var ParamsSerializer = {
|
|
59
61
|
serialize: function (queryParams) {
|
|
60
62
|
return qs_1.default.stringify(queryParams, { arrayFormat: 'brackets' });
|
|
@@ -64,12 +66,14 @@ var TastytradeHttpClient = /** @class */ (function () {
|
|
|
64
66
|
function TastytradeHttpClient(baseUrl) {
|
|
65
67
|
this.baseUrl = baseUrl;
|
|
66
68
|
this.session = new tastytrade_session_1.default();
|
|
69
|
+
this.httpsAgent = new https_1.default.Agent({ minVersion: constants_1.MinTlsVersion });
|
|
67
70
|
}
|
|
68
71
|
TastytradeHttpClient.prototype.getDefaultHeaders = function () {
|
|
69
72
|
return {
|
|
70
73
|
"Content-Type": "application/json",
|
|
71
74
|
"Accept": "application/json",
|
|
72
75
|
"Authorization": this.session.authToken,
|
|
76
|
+
"User-Agent": 'tastytrade-sdk-js'
|
|
73
77
|
};
|
|
74
78
|
};
|
|
75
79
|
TastytradeHttpClient.prototype.executeRequest = function (method, url, data, headers, params) {
|
|
@@ -89,7 +93,8 @@ var TastytradeHttpClient = /** @class */ (function () {
|
|
|
89
93
|
data: dasherizedData,
|
|
90
94
|
headers: mergedHeaders,
|
|
91
95
|
params: dasherizedParams,
|
|
92
|
-
paramsSerializer: ParamsSerializer
|
|
96
|
+
paramsSerializer: ParamsSerializer,
|
|
97
|
+
httpsAgent: this.httpsAgent
|
|
93
98
|
}, lodash_1.default.isEmpty);
|
|
94
99
|
return [2 /*return*/, axios_1.default.request(config)];
|
|
95
100
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const MinTlsVersion = "TLSv1.2";
|
package/lib/account-streamer.ts
CHANGED
|
@@ -3,6 +3,7 @@ import _ from 'lodash'
|
|
|
3
3
|
import type { JsonMap, JsonValue } from './utils/json-util'
|
|
4
4
|
import { JsonBuilder } from './utils/json-util'
|
|
5
5
|
import TastytradeSession from './models/tastytrade-session'
|
|
6
|
+
import { MinTlsVersion } from './utils/constants'
|
|
6
7
|
|
|
7
8
|
export enum STREAMER_STATE {
|
|
8
9
|
Open = 0,
|
|
@@ -123,7 +124,10 @@ export class AccountStreamer {
|
|
|
123
124
|
return this.startPromise
|
|
124
125
|
}
|
|
125
126
|
|
|
126
|
-
|
|
127
|
+
this.websocket = new WebSocket(this.url, [], {
|
|
128
|
+
minVersion: MinTlsVersion // TLS Config
|
|
129
|
+
})
|
|
130
|
+
const websocket = this.websocket
|
|
127
131
|
this.lastCloseEvent = null
|
|
128
132
|
this.lastErrorEvent = null
|
|
129
133
|
websocket.addEventListener('open', this.handleOpen)
|
|
@@ -300,7 +304,7 @@ export class AccountStreamer {
|
|
|
300
304
|
this.queued = []
|
|
301
305
|
}
|
|
302
306
|
|
|
303
|
-
private readonly handleOpen = (event: Event) => {
|
|
307
|
+
private readonly handleOpen = (event: WebSocket.Event) => {
|
|
304
308
|
if (this.startResolve === null) {
|
|
305
309
|
return
|
|
306
310
|
}
|
|
@@ -315,7 +319,7 @@ export class AccountStreamer {
|
|
|
315
319
|
this.scheduleHeartbeatTimer()
|
|
316
320
|
}
|
|
317
321
|
|
|
318
|
-
private readonly handleClose = (event: CloseEvent) => {
|
|
322
|
+
private readonly handleClose = (event: WebSocket.CloseEvent) => {
|
|
319
323
|
this.logger.info('AccountStreamer closed', event)
|
|
320
324
|
if (this.websocket === null) {
|
|
321
325
|
return
|
|
@@ -326,7 +330,7 @@ export class AccountStreamer {
|
|
|
326
330
|
this.teardown()
|
|
327
331
|
}
|
|
328
332
|
|
|
329
|
-
private readonly handleError = (event:
|
|
333
|
+
private readonly handleError = (event: WebSocket.ErrorEvent) => {
|
|
330
334
|
if (this.websocket === null) {
|
|
331
335
|
return
|
|
332
336
|
}
|
|
@@ -344,7 +348,7 @@ export class AccountStreamer {
|
|
|
344
348
|
this.teardown()
|
|
345
349
|
}
|
|
346
350
|
|
|
347
|
-
private readonly handleMessage = (event: MessageEvent) => {
|
|
351
|
+
private readonly handleMessage = (event: WebSocket.MessageEvent) => {
|
|
348
352
|
const json = JSON.parse(event.data as string) as JsonMap
|
|
349
353
|
|
|
350
354
|
if (json.results !== undefined) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import WebSocket from 'isomorphic-ws'
|
|
2
2
|
import _ from 'lodash'
|
|
3
3
|
import { v4 as uuidv4 } from 'uuid'
|
|
4
|
+
import { MinTlsVersion } from './utils/constants'
|
|
4
5
|
|
|
5
6
|
export enum MarketDataSubscriptionType {
|
|
6
7
|
Candle = 'Candle',
|
|
@@ -89,7 +90,9 @@ export default class MarketDataStreamer {
|
|
|
89
90
|
}
|
|
90
91
|
|
|
91
92
|
this.token = token
|
|
92
|
-
this.webSocket = new WebSocket(url
|
|
93
|
+
this.webSocket = new WebSocket(url, [], {
|
|
94
|
+
minVersion: MinTlsVersion // TLS Config
|
|
95
|
+
})
|
|
93
96
|
this.webSocket.onopen = this.onOpen.bind(this)
|
|
94
97
|
this.webSocket.onerror = this.onError.bind(this)
|
|
95
98
|
this.webSocket.onmessage = this.handleMessageReceived.bind(this)
|
|
@@ -343,9 +346,9 @@ export default class MarketDataStreamer {
|
|
|
343
346
|
this.errorListeners.forEach(listener => listener(error))
|
|
344
347
|
}
|
|
345
348
|
|
|
346
|
-
private handleMessageReceived(data:
|
|
347
|
-
const messageData = _.get(data, 'data',
|
|
348
|
-
const jsonData = JSON.parse(messageData)
|
|
349
|
+
private handleMessageReceived(data: WebSocket.MessageEvent) {
|
|
350
|
+
const messageData = _.get(data, 'data', '{}')
|
|
351
|
+
const jsonData = JSON.parse(messageData as string)
|
|
349
352
|
switch (jsonData.type) {
|
|
350
353
|
case 'AUTH_STATE':
|
|
351
354
|
this.handleAuthStateMessage(jsonData)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import extractResponseData from "../utils/response-util";
|
|
2
2
|
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
3
|
|
|
4
|
-
// create the central class that aggregates all services
|
|
4
|
+
// create the central class that aggregates all services
|
|
5
5
|
export default class AccountStatusService {
|
|
6
6
|
constructor(private httpClient: TastytradeHttpClient) {
|
|
7
7
|
}
|
|
@@ -30,6 +30,12 @@ export default class OrderService {
|
|
|
30
30
|
return extractResponseData(order)
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
async cancelComplexOrder(accountNumber: string, orderId: number){
|
|
34
|
+
//Requests order cancellation
|
|
35
|
+
const order = await this.httpClient.deleteData(`/accounts/${accountNumber}/complex-orders/${orderId}`, {})
|
|
36
|
+
return extractResponseData(order)
|
|
37
|
+
}
|
|
38
|
+
|
|
33
39
|
async replaceOrder(accountNumber: string, orderId: number, replacementOrder : object){
|
|
34
40
|
//Replaces a live order with a new one. Subsequent fills of the original order will abort the replacement.
|
|
35
41
|
const order = await this.httpClient.putData(`/accounts/${accountNumber}/orders/${orderId}`, replacementOrder , {})
|
|
@@ -60,6 +66,12 @@ export default class OrderService {
|
|
|
60
66
|
return extractResponseData(orderResponse)
|
|
61
67
|
}
|
|
62
68
|
|
|
69
|
+
async createComplexOrder(accountNumber: string, order: object){
|
|
70
|
+
//Accepts a json document containing parameters to create an order for the client.
|
|
71
|
+
const orderResponse = await this.httpClient.postData(`/accounts/${accountNumber}/complex-orders`, order , {})
|
|
72
|
+
return extractResponseData(orderResponse)
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
async postOrderDryRun(accountNumber: string, order: object){
|
|
64
76
|
//Accepts a json document containing parameters to create an order and then runs the prefights without placing the order.
|
|
65
77
|
const orderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/dry-run`, order , {})
|
|
@@ -3,6 +3,8 @@ import axios from "axios"
|
|
|
3
3
|
import qs from 'qs'
|
|
4
4
|
import { recursiveDasherizeKeys } from "../utils/json-util"
|
|
5
5
|
import _ from 'lodash'
|
|
6
|
+
import https from 'https'
|
|
7
|
+
import { MinTlsVersion } from "../utils/constants"
|
|
6
8
|
|
|
7
9
|
const ParamsSerializer = {
|
|
8
10
|
serialize: function (queryParams: object) {
|
|
@@ -12,9 +14,11 @@ const ParamsSerializer = {
|
|
|
12
14
|
|
|
13
15
|
export default class TastytradeHttpClient{
|
|
14
16
|
public readonly session: TastytradeSession
|
|
17
|
+
private readonly httpsAgent: https.Agent
|
|
15
18
|
|
|
16
19
|
constructor(private readonly baseUrl: string) {
|
|
17
20
|
this.session = new TastytradeSession()
|
|
21
|
+
this.httpsAgent = new https.Agent({ minVersion: MinTlsVersion })
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
private getDefaultHeaders(): any {
|
|
@@ -22,6 +26,7 @@ export default class TastytradeHttpClient{
|
|
|
22
26
|
"Content-Type": "application/json",
|
|
23
27
|
"Accept": "application/json",
|
|
24
28
|
"Authorization": this.session.authToken,
|
|
29
|
+
"User-Agent": 'tastytrade-sdk-js'
|
|
25
30
|
};
|
|
26
31
|
}
|
|
27
32
|
|
|
@@ -37,7 +42,8 @@ export default class TastytradeHttpClient{
|
|
|
37
42
|
data: dasherizedData,
|
|
38
43
|
headers: mergedHeaders,
|
|
39
44
|
params: dasherizedParams,
|
|
40
|
-
paramsSerializer: ParamsSerializer
|
|
45
|
+
paramsSerializer: ParamsSerializer,
|
|
46
|
+
httpsAgent: this.httpsAgent
|
|
41
47
|
}, _.isEmpty)
|
|
42
48
|
|
|
43
49
|
return axios.request(config)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const MinTlsVersion = 'TLSv1.2'
|
package/package.json
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tastytrade/api",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.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",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"description": "Typescript impelementation of tastytrade api",
|
|
9
|
+
"engines": {
|
|
10
|
+
"npm": ">=9.0.0",
|
|
11
|
+
"node": ">=20.0.0"
|
|
12
|
+
},
|
|
9
13
|
"scripts": {
|
|
10
14
|
"build": "tsc -p tsconfig.json",
|
|
11
15
|
"test": "jest -i --restoreMocks",
|
|
12
16
|
"unit-test": "jest --testPathPattern=tests/unit",
|
|
13
17
|
"integration-test": "jest --testPathPattern=tests/integration",
|
|
14
18
|
"lint": "eslint lib/** tests/**",
|
|
15
|
-
"prepublishOnly": "npm run test && npm run build",
|
|
19
|
+
"prepublishOnly": "npm run unit-test && npm run build",
|
|
16
20
|
"postpack": "git tag -a $npm_package_version -m $npm_package_version && git push origin $npm_package_version"
|
|
17
21
|
},
|
|
18
22
|
"dependencies": {
|
|
@@ -26,9 +30,11 @@
|
|
|
26
30
|
"ws": "^8.13.0"
|
|
27
31
|
},
|
|
28
32
|
"devDependencies": {
|
|
33
|
+
"@types/axios": "^0.14.0",
|
|
29
34
|
"@types/jest": "^29.5.0",
|
|
30
|
-
"@types/node": "
|
|
35
|
+
"@types/node": "20.9.0",
|
|
31
36
|
"@types/uuid": "^9.0.2",
|
|
37
|
+
"@types/ws": "^8.5.9",
|
|
32
38
|
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
33
39
|
"@typescript-eslint/parser": "^5.57.1",
|
|
34
40
|
"dotenv": "^16.0.3",
|