Skip to content

Commit

Permalink
feat: Add market_depth service, refactor handlers (#66)
Browse files Browse the repository at this point in the history
* feat: Add market_depth service, refactor handlers

* update readme

* update readme
  • Loading branch information
felipecsl authored Sep 10, 2023
1 parent b7bf994 commit 924464d
Show file tree
Hide file tree
Showing 24 changed files with 283 additions and 313 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,37 +1,36 @@
# TD Ameritrade WsJson API client

This is a node and browser API client for the (undocumented) TDAmeritrade WebSocket API.
This is a node and browser API client for the (undocumented) TD Ameritrade WebSocket API.

🚧 Work in progress 🚧

# Prerequisites

- Node 16+

Create a `.env` file and set your TDAmeritrade oauth access token:
Create a `.env` file and set your TD Ameritrade oauth access token:

```
CLIENT_ID=your-client-id
ACCESS_TOKEN=your-access-token
REFRESH_TOKEN=your-refresh-token
TOKEN_EXPIRES_AT=your-token-expires-at
```

# Building for Node

```
yarn install
yarn build
```

# Running the example app

```
cd example
yarn install
yarn link tda-wsjson-client
yarn start
```

# Supported APIs
Expand All @@ -52,12 +51,13 @@ yarn start
- ✅ Option chain quotes
- ✅ Option quotes
- ✅ Order events
- ✅ Market depth

# Not yet implemented

- ❌ Instrument order events
- ❌ Alert subscription
- ❌ And many others 😀
- ❌ And many more 😀

# Usage

Expand Down
114 changes: 0 additions & 114 deletions src/client/messageTypeHelpers.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,9 @@
import {
ConnectionResponse,
ParsedWebSocketResponse,
RawPayloadResponse,
WsJsonRawMessage,
} from "./tdaWsJsonTypes";
import { ChartResponse } from "./services/chartMessageHandler";
import { QuotesResponse } from "./services/quotesMessageHandler";
import { PositionsResponse } from "./services/positionsMessageHandler";
import { PlaceOrderSnapshotResponse } from "./services/placeOrderMessageHandler";
import {
OrderEventsPatchResponse,
OrderEventsResponse,
OrderEventsSnapshotResponse,
} from "./services/orderEventsMessageHandler";
import { UserPropertiesResponse } from "./services/userPropertiesMessageHandler";
import { InstrumentSearchResponse } from "./services/instrumentSearchMessageHandler";
import { AlertsResponse } from "./types/alertTypes";
import { OptionChainResponse } from "./services/optionSeriesMessageHandler";
import { RawLoginResponse } from "./services/loginMessageHandler";
import { OptionQuotesResponse } from "./services/optionQuotesMessageHandler";
import { CancelOrderResponse } from "./services/cancelOrderMessageHandler";
import {
OptionSeriesQuotesPatchResponse,
OptionSeriesQuotesSnapshotResponse,
} from "./services/optionSeriesQuotesMessageHandler";

export function isPayloadResponse(
response: WsJsonRawMessage
Expand All @@ -45,97 +25,3 @@ export function isLoginResponse(
const { service } = header;
return service === "login";
}

export function isChartResponse(
response: ParsedWebSocketResponse
): response is ChartResponse {
return "candles" in response;
}

export function isQuotesResponse(
response: ParsedWebSocketResponse
): response is QuotesResponse {
return "quotes" in response;
}

export function isPositionsResponse(
response: ParsedWebSocketResponse
): response is PositionsResponse {
return "positions" in response;
}

export function isUserPropertiesResponse(
response: ParsedWebSocketResponse
): response is UserPropertiesResponse {
return "defaultAccountCode" in response;
}

export function isPlaceOrderResponse(
response: ParsedWebSocketResponse
): response is PlaceOrderSnapshotResponse {
return "orders" in response && response.service === "place_order";
}

export function isCancelOrderResponse(
response: ParsedWebSocketResponse
): response is CancelOrderResponse {
return "service" in response && response.service === "cancel_order";
}

export function isOrderEventsPatchResponse(
response: ParsedWebSocketResponse
): response is OrderEventsPatchResponse {
return "patches" in response && response.service === "order_events";
}

export function isOrderEventsResponse(
response: ParsedWebSocketResponse
): response is OrderEventsResponse {
const isSnapshotResponse = (
response: ParsedWebSocketResponse
): response is OrderEventsSnapshotResponse =>
"orders" in response && response.service === "order_events";

return isSnapshotResponse(response) || isOrderEventsPatchResponse(response);
}

// TODO: add support for patch responses
export function isOptionQuotesResponse(
response: ParsedWebSocketResponse
): response is OptionQuotesResponse {
return "service" in response && response.service === "quotes/options";
}

export function isOptionSeriesQuotesResponse(
response: ParsedWebSocketResponse
): response is OptionSeriesQuotesSnapshotResponse {
const isSnapshotResponse = (
response: ParsedWebSocketResponse
): response is OptionSeriesQuotesSnapshotResponse =>
"series" in response && response.service === "optionSeries/quotes";

const isPatchResponse = (
response: ParsedWebSocketResponse
): response is OptionSeriesQuotesPatchResponse =>
"patches" in response && response.service === "optionSeries/quotes";

return isSnapshotResponse(response) || isPatchResponse(response);
}

export function isAlertsResponse(
response: ParsedWebSocketResponse
): response is AlertsResponse {
return "alerts" in response;
}

export function isInstrumentsResponse(
response: ParsedWebSocketResponse
): response is InstrumentSearchResponse {
return "instruments" in response;
}

export function isOptionChainResponse(
response: ParsedWebSocketResponse
): response is OptionChainResponse {
return "series" in response && response.service === "optionSeries";
}
30 changes: 26 additions & 4 deletions src/client/mockWsJsonClient.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { WsJsonClient } from "./wsJsonClient";
import { PositionsResponse } from "./services/positionsMessageHandler";
import { RawLoginResponseBody } from "./services/loginMessageHandler";
import { AlertsResponse } from "./types/alertTypes";
import { CancelOrderResponse } from "./services/cancelOrderMessageHandler";
import {
ChartRequestParams,
Expand All @@ -26,10 +25,17 @@ import { OrderEventsResponse } from "./services/orderEventsMessageHandler";
import { QuotesResponse } from "./services/quotesMessageHandler";
import { InstrumentSearchResponse } from "./services/instrumentSearchMessageHandler";
import { UserPropertiesResponse } from "./services/userPropertiesMessageHandler";
import {
CancelAlertResponse,
CreateAlertResponse,
LookupAlertsResponse,
} from "./types/alertTypes";
import { MarketDepthResponse } from "./services/marketDepthMessageHandler";

export default class MockWsJsonClient implements WsJsonClient {
async *accountPositions(_: string): AsyncIterable<PositionsResponse> {

Check warning on line 36 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'_' is defined but never used

Check warning on line 36 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used

Check warning on line 36 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (19.x)

'_' is defined but never used
return yield {
service: "positions",
positions: [],
};
}
Expand All @@ -38,8 +44,9 @@ export default class MockWsJsonClient implements WsJsonClient {
return Promise.resolve(null);
}

cancelAlert(_: number): Promise<AlertsResponse> {
cancelAlert(_: number): Promise<CancelAlertResponse> {

Check warning on line 47 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'_' is defined but never used

Check warning on line 47 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used

Check warning on line 47 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (19.x)

'_' is defined but never used
return Promise.resolve({
service: "alerts/cancel",
alerts: [],
});
}
Expand All @@ -55,13 +62,15 @@ export default class MockWsJsonClient implements WsJsonClient {

async *chart(_: ChartRequestParams): AsyncIterable<ChartResponse> {

Check warning on line 63 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'_' is defined but never used

Check warning on line 63 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used

Check warning on line 63 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (19.x)

'_' is defined but never used
return yield {
service: "chart",
symbol: "",
candles: [],
};
}

createAlert(_: CreateAlertRequestParams): Promise<AlertsResponse> {
createAlert(_: CreateAlertRequestParams): Promise<CreateAlertResponse> {

Check warning on line 71 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'_' is defined but never used

Check warning on line 71 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used

Check warning on line 71 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (19.x)

'_' is defined but never used
return Promise.resolve({
service: "alerts/create",
alerts: [],
});
}
Expand All @@ -80,8 +89,9 @@ export default class MockWsJsonClient implements WsJsonClient {
return false;
}

async *lookupAlerts(): AsyncIterable<AlertsResponse> {
async *lookupAlerts(): AsyncIterable<LookupAlertsResponse> {
return yield {
service: "alerts/lookup",
alerts: [],
};
}
Expand All @@ -97,6 +107,7 @@ export default class MockWsJsonClient implements WsJsonClient {
_: OptionChainDetailsRequest

Check warning on line 107 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (16.x)

'_' is defined but never used

Check warning on line 107 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

'_' is defined but never used

Check warning on line 107 in src/client/mockWsJsonClient.ts

View workflow job for this annotation

GitHub Actions / build (19.x)

'_' is defined but never used
): Promise<OptionChainDetailsResponse> {
return Promise.resolve({
service: "option_chain/get",
seriesDetails: [],
});
}
Expand Down Expand Up @@ -130,6 +141,7 @@ export default class MockWsJsonClient implements WsJsonClient {

async *quotes(_: string[]): AsyncIterable<QuotesResponse> {
return yield {
service: "quotes",
quotes: [],
};
}
Expand All @@ -145,12 +157,14 @@ export default class MockWsJsonClient implements WsJsonClient {

searchInstruments(_: string): Promise<InstrumentSearchResponse> {
return Promise.resolve({
service: "instrument_search",
instruments: [],
});
}

userProperties(): Promise<UserPropertiesResponse> {
return Promise.resolve({
service: "user_properties",
defaultAccountCode: "foo",
nickname: "foo",
plDisplayMethod: "foo",
Expand Down Expand Up @@ -179,4 +193,12 @@ export default class MockWsJsonClient implements WsJsonClient {
service: "order_events",
};
}

async *marketDepth(_: string): AsyncIterable<MarketDepthResponse> {
return yield {
bidQuotes: [],
askQuotes: [],
service: "market_depth",
};
}
}
Loading

0 comments on commit 924464d

Please sign in to comment.