Skip to content

Commit

Permalink
Utilize DxLink instead of DxFeed
Browse files Browse the repository at this point in the history
  • Loading branch information
dmoss18 committed Jul 18, 2023
1 parent 0416b7d commit 2a962cd
Show file tree
Hide file tree
Showing 15 changed files with 421 additions and 141 deletions.
24 changes: 15 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,36 @@ const accountPositions = await tastytradeClient.balancesAndPositionsService.getP

### Market Data
```js
import TastytradeClient, { QuoteStreamer } from "@tastytrade-api"
import TastytradeClient, { MarketDataStreamer, MarketDataSubscriptionType } from "@tastytrade-api"
const tastytradeClient = new TastytradeClient(baseUrl, accountStreamerUrl)
await tastytradeClient.sessionService.login(usernameOrEmail, pasword)
const tokenResponse = await tastytradeClient.AccountsAndCustomersService.getQuoteStreamerTokens()
const quoteStreamer = new QuoteStreamer(tokenResponse.token, `${tokenResponse['websocket-url']}/cometd`)
quoteStreamer.connect()
const tokenResponse = await tastytradeClient.AccountsAndCustomersService.getApiQuoteToken()
const streamer = new MarketDataStreamer()
streamer.connect(tokenResponse['dxlink-url'], tokenResponse.token)

function handleMarketDataReceived(event) {
function handleMarketDataReceived(data) {
// Triggers every time market data event occurs
console.log(event)
console.log(data)
}

// Add a listener for incoming market data. Returns a remove() function that removes the listener from the quote streamer
const removeDataListener = streamer.addDataListener(handleMarketDataReceived)

// Subscribe to a single equity quote
quoteStreamer.subscribe('AAPL', handleMarketDataReceived)
streamer.addSubscription('AAPL')
// Optionally specify which market data events you want to subscribe to
streamer.addSubscription('SPY', { subscriptionTypes: [MarketDataSubscriptionType.Quote] })

// Subscribe to a single equity option quote
const optionChain = await tastytradeClient.instrumentsService.getOptionChain('AAPL')
quoteStreamer.subscribe(optionChain[0]['streamer-symbol'], handleMarketDataReceived)
streamer.addSubscription(optionChain[0]['streamer-symbol'])
```

### Account Streamer
```js
const TastytradeApi = require("@tastytrade/api")
const TastytradeClient = TastytradeApi.default
const { AccountStreamer, QuoteStreamer } = TastytradeApi
const { AccountStreamer } = TastytradeApi
const _ = require('lodash')

function handleStreamerMessage(json) {
Expand Down
12 changes: 9 additions & 3 deletions examples/components/custom-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ interface Props{
}

export default function CustomTable(props:Props) {
return (
<div>
{props.rows.map(props.renderItem)}
const renderRow = (item: any, index: number) => {
<div key={index}>
{props.renderItem(item, index)}
</div>
}

return (
<>
{props.rows.map(renderRow)}
</>
)
}

Expand Down
30 changes: 18 additions & 12 deletions examples/components/subscribed-symbol.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
import { useContext, useEffect, useState } from 'react'
import _ from 'lodash'
import { AppContext } from '../contexts/context'
import Button from './button'
import { EventType } from '@dxfeed/api'
import { MarketDataSubscriptionType } from "tastytrade-api"

export default function SubscribedSymbol(props: any) {
const [bidPrice, setBidPrice] = useState(NaN)
const [askPrice, setAskPrice] = useState(NaN)

const appContext = useContext(AppContext)

const handleEvent = (event: any) => {
console.log(event)
if (event.eventType === EventType.Quote) {
setBidPrice(event.bidPrice)
setAskPrice(event.askPrice)
}
}

useEffect(() => {
const unsubscribe = appContext.quoteStreamer!.subscribe(props.symbol, handleEvent)
return unsubscribe
const removeListener = appContext.marketDataStreamer.addDataListener((event: any) => {
const eventData = _.find(event.data, data =>
data.eventType === MarketDataSubscriptionType.Quote &&
data.eventSymbol === props.symbol
)

if (!_.isNil(eventData)) {
setBidPrice(eventData.bidPrice)
setAskPrice(eventData.askPrice)
}
})

appContext.marketDataStreamer.addSubscription(props.symbol)
return () => {
appContext.marketDataStreamer.removeSubscription(props.symbol)
removeListener()
}
}, []);

return (
Expand Down
14 changes: 3 additions & 11 deletions examples/contexts/context.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
// src/context/state.ts
import { createContext } from 'react';
import TastytradeClient, { QuoteStreamer } from "tastytrade-api"
import TastytradeClient, { MarketDataStreamer } from "tastytrade-api"
import { makeAutoObservable } from 'mobx';
import _ from 'lodash'

class TastytradeContext {
static Instance = new TastytradeContext('https://api.tastyworks.com', 'wss://streamer.tastyworks.com');
static Instance = new TastytradeContext('https://api.cert.tastyworks.com', 'wss://streamer.cert.tastyworks.com');
public tastytradeApi: TastytradeClient
public accountNumbers: string[] = []
public quoteStreamer: QuoteStreamer | null = null
public readonly marketDataStreamer: MarketDataStreamer = new MarketDataStreamer()

constructor(baseUrl: string, accountStreamerUrl: string) {
makeAutoObservable(this)
this.tastytradeApi = new TastytradeClient(baseUrl, accountStreamerUrl)
makeAutoObservable(this.tastytradeApi.session)
}

setupQuoteStreamer(token: string, url: string) {
if (_.isNil(this.quoteStreamer)) {
this.quoteStreamer = new QuoteStreamer(token, url)
}

return this.quoteStreamer
}

get isLoggedIn() {
return this.tastytradeApi.session.isValid
}
Expand Down
2 changes: 1 addition & 1 deletion examples/next.config.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
reactStrictMode: false
}

module.exports = nextConfig
16 changes: 11 additions & 5 deletions examples/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion examples/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useMemo } from 'react'
function MyApp({ Component, pageProps }: AppProps) {

const context = useMemo(
() => new TastytradeContext('https://api.tastyworks.com', 'wss://streamer.tastyworks.com'),
() => new TastytradeContext('https://api.tastyworks.com', 'wss://streamer.cert.tastyworks.com'),
[]
);
return (
Expand Down
15 changes: 7 additions & 8 deletions examples/pages/quote-streamer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ const Home: NextPage = () => {
const appContext = useContext(AppContext)

useEffect(() => {
appContext.tastytradeApi.accountsAndCustomersService.getQuoteStreamerTokens()
appContext.tastytradeApi.accountsAndCustomersService.getApiQuoteToken()
.then(response => {
const url = `${response['websocket-url']}/cometd`
const quoteStreamer = appContext.setupQuoteStreamer(response.token, url)
quoteStreamer.connect()
if (appContext.marketDataStreamer.isConnected) {
return
}
appContext.marketDataStreamer.connect(response['dxlink-url'], response.token)
setLoading(false)
})

return () => {
if (!_.isNil(appContext.quoteStreamer)) {
appContext.quoteStreamer.disconnect()
}
appContext.marketDataStreamer.disconnect()
}
}, []);

Expand All @@ -48,7 +47,7 @@ const Home: NextPage = () => {
return (
<div>
<h1 className="my-3 text-xl font-bold">
DxFeed Quotes Demo
DxLink Quotes Demo
</h1>
<div className='my-1'>Type a symbol into the input and click 'Add Symbol'</div>

Expand Down
Loading

0 comments on commit 2a962cd

Please sign in to comment.