@tastytrade/api 0.0.1
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 +5 -0
- package/.eslintrc.cjs +18 -0
- package/.vscode/launch.json +24 -0
- package/LICENSE +21 -0
- package/README.md +21 -0
- package/dist/account-streamer.d.ts +92 -0
- package/dist/account-streamer.js +394 -0
- package/dist/models/tastytrade-session.d.ts +5 -0
- package/dist/models/tastytrade-session.js +23 -0
- package/dist/quote-streamer.d.ts +11 -0
- package/dist/quote-streamer.js +63 -0
- package/dist/services/account-status-service.d.ts +6 -0
- package/dist/services/account-status-service.js +64 -0
- package/dist/services/accounts-and-customers-service.d.ts +10 -0
- package/dist/services/accounts-and-customers-service.js +116 -0
- package/dist/services/balances-and-positions-service.d.ts +8 -0
- package/dist/services/balances-and-positions-service.js +93 -0
- package/dist/services/instruments-service.d.ts +28 -0
- package/dist/services/instruments-service.js +370 -0
- package/dist/services/margin-requirements-service.d.ts +7 -0
- package/dist/services/margin-requirements-service.js +76 -0
- package/dist/services/market-metrics-service.d.ts +8 -0
- package/dist/services/market-metrics-service.js +91 -0
- package/dist/services/net-liquidating-value-history-service.d.ts +7 -0
- package/dist/services/net-liquidating-value-history-service.js +77 -0
- package/dist/services/orders-service.d.ts +17 -0
- package/dist/services/orders-service.js +208 -0
- package/dist/services/risk-parameters-service.d.ts +7 -0
- package/dist/services/risk-parameters-service.js +76 -0
- package/dist/services/session-service.d.ts +9 -0
- package/dist/services/session-service.js +113 -0
- package/dist/services/symbol-search-service.d.ts +6 -0
- package/dist/services/symbol-search-service.js +63 -0
- package/dist/services/tastytrade-http-client.d.ts +13 -0
- package/dist/services/tastytrade-http-client.js +137 -0
- package/dist/services/transactions-service.d.ts +8 -0
- package/dist/services/transactions-service.js +91 -0
- package/dist/services/watchlists-service.d.ts +14 -0
- package/dist/services/watchlists-service.js +170 -0
- package/dist/tastytrade-api.d.ts +40 -0
- package/dist/tastytrade-api.js +56 -0
- package/dist/utils/json-util.d.ts +14 -0
- package/dist/utils/json-util.js +43 -0
- package/dist/utils/response-util.d.ts +1 -0
- package/dist/utils/response-util.js +21 -0
- package/lib/account-streamer.ts +394 -0
- package/lib/models/tastytrade-session.ts +13 -0
- package/lib/quote-streamer.ts +40 -0
- package/lib/services/account-status-service.ts +15 -0
- package/lib/services/accounts-and-customers-service.ts +35 -0
- package/lib/services/balances-and-positions-service.ts +29 -0
- package/lib/services/instruments-service.ts +138 -0
- package/lib/services/margin-requirements-service.ts +19 -0
- package/lib/services/market-metrics-service.ts +24 -0
- package/lib/services/net-liquidating-value-history-service.ts +20 -0
- package/lib/services/orders-service.ts +80 -0
- package/lib/services/risk-parameters-service.ts +19 -0
- package/lib/services/session-service.ts +35 -0
- package/lib/services/symbol-search-service.ts +14 -0
- package/lib/services/tastytrade-http-client.ts +65 -0
- package/lib/services/transactions-service.ts +27 -0
- package/lib/services/watchlists-service.ts +58 -0
- package/lib/tastytrade-api.ts +65 -0
- package/lib/utils/json-util.ts +44 -0
- package/lib/utils/response-util.ts +15 -0
- package/package.json +35 -0
- package/tsconfig.json +71 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class MarketMetricsService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Default
|
|
9
|
+
async getMarketMetrics(queryParams = {}){
|
|
10
|
+
//Returns an array of volatility data for given symbols.
|
|
11
|
+
const marketMetrics = (await this.httpClient.getData('/market-metrics', {}, queryParams))
|
|
12
|
+
return extractResponseData(marketMetrics)
|
|
13
|
+
}
|
|
14
|
+
async getHistoricalDividendData(symbol: string){
|
|
15
|
+
//Get historical dividend data
|
|
16
|
+
const historicalDividendData = (await this.httpClient.getData(`/market-metrics/historic-corporate-events/dividends/${symbol}`, {}, {}))
|
|
17
|
+
return extractResponseData(historicalDividendData)
|
|
18
|
+
}
|
|
19
|
+
async getHistoricalEarningsData(symbol: string, queryParams = {}){
|
|
20
|
+
//Get historical earnings data
|
|
21
|
+
const historicalEarningsData = (await this.httpClient.getData(`/market-metrics/historic-corporate-events/earnings-reports/${symbol}`, {}, queryParams))
|
|
22
|
+
return extractResponseData(historicalEarningsData)
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class NetLiquidatingValueHistoryService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Default
|
|
9
|
+
async getNetLiquidatingValueHistory(accountNumber: string, queryParams = {}){
|
|
10
|
+
//Returns a list of account net liquidating value snapshots.
|
|
11
|
+
const netLiquidatingValueHistory = (await this.httpClient.getData(`/accounts/${accountNumber}/net-liq/history`, {}, queryParams))
|
|
12
|
+
return extractResponseData(netLiquidatingValueHistory)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async getNetLiquidatingValue(accountNumber: string){
|
|
16
|
+
//Returns a list of account net liquidating value snapshots.
|
|
17
|
+
const netLiquidatingValue = await this.httpClient.getData(`/accounts/${accountNumber}/net-liq`)
|
|
18
|
+
return extractResponseData(netLiquidatingValue)
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class OrderService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Orders: Allows an API client to view, filter, create, cancel and replace orders.
|
|
9
|
+
async postReconfirmOrder(accountNumber: string, orderId: number){
|
|
10
|
+
//Reconfirm an order
|
|
11
|
+
const reconfirmOrder = await this.httpClient.postData(`/accounts/${accountNumber}/orders/${orderId}/reconfirm`, {}, {})
|
|
12
|
+
return extractResponseData(reconfirmOrder)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async replacementOrderDryRun(accountNumber: string, orderId: number, replacementOrder: object){
|
|
16
|
+
//Runs through preflights for cancel-replace and edit without routing
|
|
17
|
+
const replacementOrderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/${orderId}/dry-run`, replacementOrder, {})
|
|
18
|
+
return extractResponseData(replacementOrderDryRun)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getOrder(accountNumber: string, orderId: number){
|
|
22
|
+
//Returns an order based on the orderId
|
|
23
|
+
const order = await this.httpClient.getData(`/accounts/${accountNumber}/orders/${orderId}`, {}, {})
|
|
24
|
+
return extractResponseData(order)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async cancelOrder(accountNumber: string, orderId: number){
|
|
28
|
+
//Requests order cancellation
|
|
29
|
+
const order = await this.httpClient.deleteData(`/accounts/${accountNumber}/orders/${orderId}`, {})
|
|
30
|
+
return extractResponseData(order)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
async replaceOrder(accountNumber: string, orderId: number, replacementOrder : object){
|
|
34
|
+
//Replaces a live order with a new one. Subsequent fills of the original order will abort the replacement.
|
|
35
|
+
const order = await this.httpClient.putData(`/accounts/${accountNumber}/orders/${orderId}`, replacementOrder , {})
|
|
36
|
+
return extractResponseData(order)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async editOrder(accountNumber: string, orderId: number, order : object){
|
|
40
|
+
//Edit price and execution properties of a live order by replacement. Subsequent fills of the original order will abort the replacement.
|
|
41
|
+
const orderResponse = await this.httpClient.patchData(`/accounts/${accountNumber}/orders/${orderId}`, order , {})
|
|
42
|
+
return extractResponseData(orderResponse)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async getLiveOrders(accountNumber: string){
|
|
46
|
+
//Returns a list of live orders for the resource
|
|
47
|
+
const liveOrders = await this.httpClient.getData(`/accounts/${accountNumber}/orders/live`, {}, {})
|
|
48
|
+
return extractResponseData(liveOrders)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async getOrders(accountNumber: string, queryParams = {}){
|
|
52
|
+
//Returns a paginated list of the customer's orders (as identified by the provided authentication token) based on sort param. If no sort is passed in, it defaults to descending order.
|
|
53
|
+
const orders = await this.httpClient.getData(`/accounts/${accountNumber}/orders`, {}, queryParams)
|
|
54
|
+
return extractResponseData(orders)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
async createOrder(accountNumber: string, order: object){
|
|
58
|
+
//Accepts a json document containing parameters to create an order for the client.
|
|
59
|
+
const orderResponse = await this.httpClient.postData(`/accounts/${accountNumber}/orders`, order , {})
|
|
60
|
+
return extractResponseData(orderResponse)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async postOrderDryRun(accountNumber: string, order: object){
|
|
64
|
+
//Accepts a json document containing parameters to create an order and then runs the prefights without placing the order.
|
|
65
|
+
const orderDryRun = await this.httpClient.postData(`/accounts/${accountNumber}/orders/dry-run`, order , {})
|
|
66
|
+
return extractResponseData(orderDryRun)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async getLiveOrdersForCustomer(customerId: string){
|
|
70
|
+
//Returns a list of live orders for the resource
|
|
71
|
+
const liveOrders = await this.httpClient.getData(`/customers/${customerId}/orders/live`, {}, {})
|
|
72
|
+
return extractResponseData(liveOrders)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async getCustomerOrders(customerId: string, queryParams = {}){
|
|
76
|
+
//Returns a paginated list of the customer's orders (as identified by the provided authentication token) based on sort param. If no sort is passed in, it defaults to descending order.
|
|
77
|
+
const customerOrders = await this.httpClient.getData(`/customers/${customerId}/orders`, {}, queryParams)
|
|
78
|
+
return extractResponseData(customerOrders)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class RiskParametersService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Accounts: Operations about accounts
|
|
9
|
+
async getEffectiveMarginRequirements(accountNumber: string, underlyingSymbol: string){
|
|
10
|
+
//Get effective margin requirements for account
|
|
11
|
+
const effectiveMarginRequirements = (await this.httpClient.getData(`/accounts/${accountNumber}/margin-requirements/${underlyingSymbol}/effective`, {}, {}))
|
|
12
|
+
return extractResponseData(effectiveMarginRequirements)
|
|
13
|
+
}
|
|
14
|
+
async getPositionLimit(accountNumber: string){
|
|
15
|
+
//Get the position limit
|
|
16
|
+
const positionLimit = (await this.httpClient.getData(`/accounts/${accountNumber}/position-limit`, {}, {}))
|
|
17
|
+
return extractResponseData(positionLimit)
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class SessionService {
|
|
5
|
+
constructor(public httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Sessions: Allows an API client to interact with their session, or create a new one.
|
|
9
|
+
async login(usernameOrEmail: string, password: string, rememberMe = false) {
|
|
10
|
+
// Create a new user session.
|
|
11
|
+
const params = { login: usernameOrEmail, password, rememberMe }
|
|
12
|
+
const sessionResponse = await this.httpClient.postData('/sessions', params, {})
|
|
13
|
+
const sessionData = extractResponseData(sessionResponse)
|
|
14
|
+
this.httpClient.session.authToken = sessionData["session-token"]
|
|
15
|
+
return sessionData
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async loginWithRememberToken(usernameOrEmail: string, rememberToken: string, rememberMe = false){
|
|
19
|
+
// Creates a session using the remember token.
|
|
20
|
+
const params = { login: usernameOrEmail, rememberToken, rememberMe }
|
|
21
|
+
const sessionData = extractResponseData(await this.httpClient.postData('/sessions', params, {}))
|
|
22
|
+
this.httpClient.session.authToken = sessionData["session-token"]
|
|
23
|
+
return sessionData
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async validate() {
|
|
27
|
+
const response = await this.httpClient.postData('/sessions/validate', {}, {});
|
|
28
|
+
return extractResponseData(response);
|
|
29
|
+
}
|
|
30
|
+
async logout(){
|
|
31
|
+
const response = await this.httpClient.deleteData('/sessions', {});// added this for the integration tests?
|
|
32
|
+
this.httpClient.session.clear()
|
|
33
|
+
return extractResponseData(response);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class SymbolSearchService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Default
|
|
9
|
+
async getSymbolData(symbol: string){
|
|
10
|
+
//Returns an array of symbol data.
|
|
11
|
+
const symbolData = (await this.httpClient.getData(`/symbols/search/${symbol}`, {}, {}))
|
|
12
|
+
return extractResponseData(symbolData)
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import TastytradeSession from "../models/tastytrade-session"
|
|
2
|
+
import axios from "axios"
|
|
3
|
+
import qs from 'qs'
|
|
4
|
+
import { recursiveDasherizeKeys } from "../utils/json-util"
|
|
5
|
+
import _ from 'lodash'
|
|
6
|
+
|
|
7
|
+
const ParamsSerializer = {
|
|
8
|
+
serialize: function (queryParams: object) {
|
|
9
|
+
return qs.stringify(queryParams, { arrayFormat: 'brackets' })
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default class TastytradeHttpClient{
|
|
14
|
+
public readonly session: TastytradeSession
|
|
15
|
+
|
|
16
|
+
constructor(private readonly baseUrl: string) {
|
|
17
|
+
this.session = new TastytradeSession()
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
private getDefaultHeaders(): any {
|
|
21
|
+
return {
|
|
22
|
+
"Content-Type": "application/json",
|
|
23
|
+
"Accept": "application/json",
|
|
24
|
+
"Authorization": this.session.authToken,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private async executeRequest(method: string, url: string, data: object = {}, headers: object = {}, params: object = {}) {
|
|
29
|
+
const dasherizedParams = recursiveDasherizeKeys(params)
|
|
30
|
+
const dasherizedData = recursiveDasherizeKeys(data)
|
|
31
|
+
const mergedHeaders = { ...headers, ...this.getDefaultHeaders() }
|
|
32
|
+
|
|
33
|
+
const config = _.omitBy({
|
|
34
|
+
method,
|
|
35
|
+
url,
|
|
36
|
+
baseURL: this.baseUrl,
|
|
37
|
+
data: dasherizedData,
|
|
38
|
+
headers: mergedHeaders,
|
|
39
|
+
params: dasherizedParams,
|
|
40
|
+
paramsSerializer: ParamsSerializer
|
|
41
|
+
}, _.isEmpty)
|
|
42
|
+
|
|
43
|
+
return axios.request(config)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async getData(url: string, headers: object = {}, queryParams: object = {}): Promise<any> {
|
|
47
|
+
return this.executeRequest('get', url, {}, headers, queryParams);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async postData(url: string, data: object, headers: object): Promise<any> {
|
|
51
|
+
return this.executeRequest('post', url, data, headers);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async putData(url: string, data: object, headers: object): Promise<any> {
|
|
55
|
+
return this.executeRequest('put', url, data, headers);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async patchData(url: string, data: object, headers: object): Promise<any> {
|
|
59
|
+
return this.executeRequest('patch', url, data, headers);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
async deleteData(url: string, headers: object): Promise<any> {
|
|
63
|
+
return this.executeRequest('delete', url, headers);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class TransactionsService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Accounts: Operations about Accounts
|
|
9
|
+
async getTransaction(accountNumber: string, id: string){
|
|
10
|
+
//Retrieve a transaction by account number and ID
|
|
11
|
+
const symbolData = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions/${id}`, {}, {}))
|
|
12
|
+
return extractResponseData(symbolData)
|
|
13
|
+
}
|
|
14
|
+
async getTotalFees(accountNumber: string){
|
|
15
|
+
//Return the total fees for an account for a given day
|
|
16
|
+
const totalFees = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions/total-fees`, {}, {}))
|
|
17
|
+
return extractResponseData(totalFees)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//Transactions: Operations about transactions
|
|
21
|
+
async getAccountTransactions(accountNumber: string, queryParams = {}){
|
|
22
|
+
//Returns a paginated list of the account's transactions (as identified by the provided authentication token)
|
|
23
|
+
//based on sort param. If no sort is passed in, it defaults to descending order.
|
|
24
|
+
const accountTransactions = (await this.httpClient.getData(`/accounts/${accountNumber}/transactions`, {}, queryParams))
|
|
25
|
+
return extractResponseData(accountTransactions)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import extractResponseData from "../utils/response-util";
|
|
2
|
+
import TastytradeHttpClient from "./tastytrade-http-client";
|
|
3
|
+
|
|
4
|
+
export default class WatchlistsService {
|
|
5
|
+
constructor(private httpClient: TastytradeHttpClient) {
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
//Pairs Watchlists: Allows an API client to fetch pairs watchlists.
|
|
9
|
+
async getPairsWatchlists(){
|
|
10
|
+
//Returns a list of all tastyworks pairs watchlists
|
|
11
|
+
const pairsWatchlists = await this.httpClient.getData(`/pairs-watchlists`, {}, {})
|
|
12
|
+
return extractResponseData(pairsWatchlists)
|
|
13
|
+
}
|
|
14
|
+
async getPairsWatchlist(pairsWatchlistName: string){
|
|
15
|
+
//Returns a requested tastyworks pairs watchlist
|
|
16
|
+
const pairsWatchlist = await this.httpClient.getData(`/pairs-watchlists/${pairsWatchlistName}`, {}, {})
|
|
17
|
+
return extractResponseData(pairsWatchlist)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
//Public Watchlists: Allows an API client to fetch tastyworks watchlists.
|
|
21
|
+
async getPublicWatchlists(countsOnly = false){
|
|
22
|
+
//Returns a list of all tastyworks watchlists
|
|
23
|
+
const publicWatchlists = await this.httpClient.getData(`/public-watchlists`, {}, {'counts-only': countsOnly })
|
|
24
|
+
return extractResponseData(publicWatchlists)
|
|
25
|
+
}
|
|
26
|
+
async getPublicWatchlist(watchlistName: string){
|
|
27
|
+
//Returns a requested tastyworks watchlist
|
|
28
|
+
const publicWatchlist = await this.httpClient.getData(`/public-watchlists/${watchlistName}`, {}, {})
|
|
29
|
+
return extractResponseData(publicWatchlist)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//User Watchlists: Allows an API client to fetch a user's watchlists.
|
|
33
|
+
async createAccountWatchlist(watchlist: object){
|
|
34
|
+
//Create an account watchlist
|
|
35
|
+
const accountWatchlist = await this.httpClient.postData(`/watchlists`, watchlist, {})
|
|
36
|
+
return extractResponseData(accountWatchlist)
|
|
37
|
+
}
|
|
38
|
+
async getAllWatchlists(){
|
|
39
|
+
//Returns a list of all watchlists for the given account
|
|
40
|
+
const allWatchlists = await this.httpClient.getData(`/watchlists`, {}, {})
|
|
41
|
+
return extractResponseData(allWatchlists)
|
|
42
|
+
}
|
|
43
|
+
async replaceWatchlist(watchlistName: string, replacementWatchlist: object){
|
|
44
|
+
//Replace all properties of an account watchlist
|
|
45
|
+
const watchlist = await this.httpClient.putData(`/watchlists/${watchlistName}`, replacementWatchlist , {})
|
|
46
|
+
return extractResponseData(watchlist)
|
|
47
|
+
}
|
|
48
|
+
async deleteWatchlist(watchlistName: string){
|
|
49
|
+
//Delete a watchlist for the given account
|
|
50
|
+
const watchlist = await this.httpClient.deleteData(`/watchlists/${watchlistName}`, {})
|
|
51
|
+
return extractResponseData(watchlist)
|
|
52
|
+
}
|
|
53
|
+
async getSingleWatchlist(watchlistName: string){
|
|
54
|
+
//Returns a requested account watchlist
|
|
55
|
+
const singleWatchlist = await this.httpClient.getData(`/watchlists/${watchlistName}`, {}, {})
|
|
56
|
+
return extractResponseData(singleWatchlist)
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import TastytradeHttpClient from "./services/tastytrade-http-client"
|
|
2
|
+
import { AccountStreamer, STREAMER_STATE, Disposer, StreamerStateObserver } from './account-streamer'
|
|
3
|
+
import QuoteStreamer from "./quote-streamer"
|
|
4
|
+
|
|
5
|
+
//Services:
|
|
6
|
+
import SessionService from "./services/session-service"
|
|
7
|
+
import AccountStatusService from "./services/account-status-service"
|
|
8
|
+
import AccountsAndCustomersService from "./services/accounts-and-customers-service"
|
|
9
|
+
import BalancesAndPositionsService from "./services/balances-and-positions-service"
|
|
10
|
+
import InstrumentsService from "./services/instruments-service"
|
|
11
|
+
import MarginRequirementsService from "./services/margin-requirements-service"
|
|
12
|
+
import MarketMetricsService from "./services/market-metrics-service"
|
|
13
|
+
import NetLiquidatingValueHistoryService from "./services/net-liquidating-value-history-service"
|
|
14
|
+
import OrderService from "./services/orders-service"
|
|
15
|
+
import RiskParametersService from "./services/risk-parameters-service"
|
|
16
|
+
import SymbolSearchService from "./services/symbol-search-service"
|
|
17
|
+
import TransactionsService from "./services/transactions-service"
|
|
18
|
+
import WatchlistsService from "./services/watchlists-service"
|
|
19
|
+
import TastytradeSession from "./models/tastytrade-session"
|
|
20
|
+
|
|
21
|
+
export default class TastytradeClient {
|
|
22
|
+
public readonly httpClient: TastytradeHttpClient
|
|
23
|
+
|
|
24
|
+
public readonly accountStreamer: AccountStreamer
|
|
25
|
+
|
|
26
|
+
public readonly sessionService: SessionService
|
|
27
|
+
public readonly accountStatusService: AccountStatusService
|
|
28
|
+
public readonly accountsAndCustomersService: AccountsAndCustomersService
|
|
29
|
+
public readonly balancesAndPositionsService: BalancesAndPositionsService
|
|
30
|
+
public readonly instrumentsService: InstrumentsService
|
|
31
|
+
public readonly marginRequirementsService: MarginRequirementsService
|
|
32
|
+
public readonly marketMetricsService: MarketMetricsService
|
|
33
|
+
public readonly netLiquidatingValueHistoryService: NetLiquidatingValueHistoryService
|
|
34
|
+
public readonly orderService: OrderService
|
|
35
|
+
public readonly riskParametersService: RiskParametersService
|
|
36
|
+
public readonly symbolSearchService: SymbolSearchService
|
|
37
|
+
public readonly transactionsService: TransactionsService
|
|
38
|
+
public readonly watchlistsService: WatchlistsService
|
|
39
|
+
|
|
40
|
+
constructor(readonly baseUrl: string, readonly accountStreamerUrl: string) {
|
|
41
|
+
this.httpClient = new TastytradeHttpClient(baseUrl)
|
|
42
|
+
this.accountStreamer = new AccountStreamer(accountStreamerUrl, this.session)
|
|
43
|
+
|
|
44
|
+
this.sessionService = new SessionService(this.httpClient)
|
|
45
|
+
this.accountStatusService = new AccountStatusService(this.httpClient)
|
|
46
|
+
this.accountsAndCustomersService = new AccountsAndCustomersService(this.httpClient)
|
|
47
|
+
this.balancesAndPositionsService = new BalancesAndPositionsService(this.httpClient)
|
|
48
|
+
this.instrumentsService = new InstrumentsService(this.httpClient)
|
|
49
|
+
this.marginRequirementsService = new MarginRequirementsService(this.httpClient)
|
|
50
|
+
this.marketMetricsService = new MarketMetricsService(this.httpClient)
|
|
51
|
+
this.netLiquidatingValueHistoryService = new NetLiquidatingValueHistoryService(this.httpClient)
|
|
52
|
+
this.orderService = new OrderService(this.httpClient)
|
|
53
|
+
this.riskParametersService = new RiskParametersService(this.httpClient)
|
|
54
|
+
this.symbolSearchService = new SymbolSearchService(this.httpClient)
|
|
55
|
+
this.transactionsService = new TransactionsService(this.httpClient)
|
|
56
|
+
this.watchlistsService = new WatchlistsService(this.httpClient)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
get session(): TastytradeSession {
|
|
60
|
+
return this.httpClient.session
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export { QuoteStreamer }
|
|
65
|
+
export { AccountStreamer, STREAMER_STATE, Disposer, StreamerStateObserver }
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
|
|
3
|
+
export type BasicJsonValue = boolean | number | string | null | undefined
|
|
4
|
+
export type JsonValue = BasicJsonValue | JsonArray | JsonMap
|
|
5
|
+
export interface JsonMap {
|
|
6
|
+
[key: string]: JsonValue | undefined
|
|
7
|
+
}
|
|
8
|
+
export type JsonArray = JsonValue[]
|
|
9
|
+
|
|
10
|
+
export class JsonBuilder {
|
|
11
|
+
public constructor(public readonly json: JsonMap = {}) {}
|
|
12
|
+
|
|
13
|
+
public add(key: string, value: JsonValue, serializeEmpty = false): this {
|
|
14
|
+
if ((_.isNil(value) || value === '') && !serializeEmpty) {
|
|
15
|
+
return this
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
this.json[key] = value
|
|
19
|
+
return this
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
24
|
+
export function recursiveDasherizeKeys(body: any) {
|
|
25
|
+
let dasherized = _.mapKeys(body, (_value, key) => dasherize(key))
|
|
26
|
+
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
28
|
+
dasherized = _.mapValues(dasherized, (value: any) => {
|
|
29
|
+
if (_.isPlainObject(value)) {
|
|
30
|
+
return recursiveDasherizeKeys(value)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return value
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
return dasherized
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function dasherize(target: string): string {
|
|
40
|
+
// prettier-ignore
|
|
41
|
+
return target
|
|
42
|
+
.replace(/([A-Z])/g, (_match, p1: string, _offset, _whole) => `-${p1.toLowerCase()}`)
|
|
43
|
+
.replace(/\s/g, '-')
|
|
44
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import _ from 'lodash'
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
4
|
+
export default function extractResponseData(httpResponse: any){
|
|
5
|
+
if (_.has(httpResponse, 'data.data.items')) {
|
|
6
|
+
return _.get(httpResponse, 'data.data.items')
|
|
7
|
+
} else if (_.has(httpResponse, 'data.data')){
|
|
8
|
+
return _.get(httpResponse, 'data.data')
|
|
9
|
+
}else{
|
|
10
|
+
return httpResponse
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// add login parser here
|
|
15
|
+
// create unit tests for login parser, extractreponsedata
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tastytrade/api",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"main": "dist/tastytrade-api.js",
|
|
5
|
+
"typings": "dist/tastytrade-api.d.ts",
|
|
6
|
+
"repository": "https://github.com/tastytrade/tastytrade-api-js",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"description": "Typescript impelementation of tastytrade api",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "tsc -p tsconfig.json",
|
|
11
|
+
"test": "jest -i --restoreMocks",
|
|
12
|
+
"unit-test": "jest --testPathPattern=tests/unit",
|
|
13
|
+
"integration-test": "jest --testPathPattern=tests/integration",
|
|
14
|
+
"lint": "eslint lib/** tests/**"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@dxfeed/api": "^1.1.0",
|
|
18
|
+
"@types/lodash": "^4.14.182",
|
|
19
|
+
"@types/qs": "^6.9.7",
|
|
20
|
+
"axios": "^1.3.4",
|
|
21
|
+
"lodash": "^4.17.21",
|
|
22
|
+
"qs": "^6.11.1"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@types/jest": "^29.5.0",
|
|
26
|
+
"@types/node": "17.0.27",
|
|
27
|
+
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
|
28
|
+
"@typescript-eslint/parser": "^5.57.1",
|
|
29
|
+
"dotenv": "^16.0.3",
|
|
30
|
+
"eslint": "^8.14.0",
|
|
31
|
+
"jest": "^29.5.0",
|
|
32
|
+
"ts-jest": "^29.0.5",
|
|
33
|
+
"typescript": "4.6.3"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
/* Visit https://aka.ms/tsconfig.json to read more about this file */
|
|
4
|
+
|
|
5
|
+
/* Basic Options */
|
|
6
|
+
// "incremental": true, /* Enable incremental compilation */
|
|
7
|
+
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
|
|
8
|
+
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
|
|
9
|
+
// "lib": [], /* Specify library files to be included in the compilation. */
|
|
10
|
+
"allowJs": true, /* Allow javascript files to be compiled. */
|
|
11
|
+
// "checkJs": true, /* Report errors in .js files. */
|
|
12
|
+
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
|
13
|
+
"declaration": true, /* Generates corresponding '.d.ts' file. */
|
|
14
|
+
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
|
15
|
+
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
|
16
|
+
// "outFile": "./", /* Concatenate and emit output to single file. */
|
|
17
|
+
"outDir": "./dist", /* Redirect output structure to the directory. */
|
|
18
|
+
// "rootDir": "./lib", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
|
19
|
+
// "composite": true, /* Enable project compilation */
|
|
20
|
+
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
|
21
|
+
// "removeComments": true, /* Do not emit comments to output. */
|
|
22
|
+
// "noEmit": true, /* Do not emit outputs. */
|
|
23
|
+
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
|
24
|
+
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
|
25
|
+
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
|
26
|
+
|
|
27
|
+
/* Strict Type-Checking Options */
|
|
28
|
+
"strict": true, /* Enable all strict type-checking options. */
|
|
29
|
+
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
|
30
|
+
// "strictNullChecks": true, /* Enable strict null checks. */
|
|
31
|
+
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
|
32
|
+
// "strictBindCallApply": true, /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
|
|
33
|
+
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
|
34
|
+
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
|
35
|
+
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
|
36
|
+
|
|
37
|
+
/* Additional Checks */
|
|
38
|
+
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
|
39
|
+
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
|
40
|
+
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
|
41
|
+
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
|
42
|
+
|
|
43
|
+
/* Module Resolution Options */
|
|
44
|
+
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
|
45
|
+
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
|
46
|
+
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
|
47
|
+
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
|
48
|
+
// "typeRoots": [], /* List of folders to include type definitions from. */
|
|
49
|
+
// "types": [], /* Type declaration files to be included in compilation. */
|
|
50
|
+
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
|
51
|
+
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
|
52
|
+
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
|
53
|
+
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
|
|
54
|
+
|
|
55
|
+
/* Source Map Options */
|
|
56
|
+
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
|
57
|
+
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
|
58
|
+
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
|
59
|
+
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
|
60
|
+
|
|
61
|
+
/* Experimental Options */
|
|
62
|
+
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
|
63
|
+
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
|
64
|
+
|
|
65
|
+
/* Advanced Options */
|
|
66
|
+
"skipLibCheck": true, /* Skip type checking of declaration files. */
|
|
67
|
+
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
|
68
|
+
},
|
|
69
|
+
"include": ["lib/**/*"],
|
|
70
|
+
"exclude": ["node_modules", "dist", "tests/**/*", "examples"]
|
|
71
|
+
}
|