Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import { IExchangeOrder, IOrderBook, IOrderBookEntry, IOrderBookFeed } from "../3d/interfaces";
- import { MarketSide, OrderStatus, OrderSide, ExchangeName, InstrumentSymbol } from "./enums";
- import { disconnect } from "cluster";
- export class OrderBookEntry implements IOrderBookEntry
- {
- constructor(public symbol:InstrumentSymbol,
- public side: MarketSide,
- public price: number,
- public quantity: number)
- {
- }
- }
- export class OrderBookFeed implements IOrderBookFeed
- {
- constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook: OrderBook)
- {
- console.log("Constructing Orderbook Feed");
- }
- loadBook()
- {
- throw new Error("Implement in subclass");
- }
- openFeed()
- {
- throw new Error("Implement in subclass");
- }
- closeFeed()
- {
- throw new Error("Implement in subclass");
- }
- processUpdate()
- {
- throw new Error("Implement in subclass");
- }
- }
- export class CryptoQuoteFeed extends OrderBookFeed
- {
- private webSocket:WebSocket;
- private feedUrl: string = 'wss://feed.cryptoquote.io';
- private cryptoquoteKey: string = "e1983f70-a7e9-11e8-8362-5b2454c11240";
- constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook:OrderBook)
- {
- super(exchange,symbol, orderBook);
- console.log("Constructing Orderbook Feed");
- }
- createUrl(symbol: InstrumentSymbol, exchange: ExchangeName, interval: number) : string
- {
- let symbolString:string;
- let exchangeString:string;
- switch(symbol)
- {
- case InstrumentSymbol.USD_BTC:
- symbolString = "BTCUSD";
- break;
- }
- switch(exchange)
- {
- case ExchangeName.CryptoQuote:
- exchangeString = "Binance";
- break;
- }
- return `https://feed.cryptoquote.io/api/v1/book/${symbolString}.${exchangeString}/${interval}`;
- }
- async loadBook(): Promise<void>
- {
- try {
- const url: string = this.createUrl(this.symbol, this.exchange, 100);
- console.log("Book Url: " + url);
- const response: Response = await fetch(url);
- const bData = await response.json();
- bData.bids.forEach((bid: any) => {
- let entry:OrderBookEntry = new OrderBookEntry(this.symbol,
- MarketSide.Bid,
- bid[0],
- bid[1].size)
- this.orderBook.bids.push(entry)
- });
- this.orderBook.bids = this.orderBook.bids.sort(this.orderBook.compareBids);
- bData.asks.forEach((ask: any) => {
- let entry:OrderBookEntry = new OrderBookEntry(this.symbol,
- MarketSide.Ask,
- ask[0],
- ask[1].size)
- this.orderBook.asks.push(entry)
- });
- this.orderBook.asks = this.orderBook.asks.sort(this.orderBook.compareAsks);
- this.orderBook.refresh();
- } catch (e) {
- console.log('fetch error: ', e);
- }
- }
- openFeed()
- {
- this.webSocket = new WebSocket(`${this.feedUrl}/v1/firehose/${this.cryptoquoteKey}?services=book`);
- this.webSocket.onmessage = (event: any) => {
- const m: any = JSON.parse(event.data);
- if (m.updateType === 'book_update' && m.exchange.name === this.exchange && m.symbol === this.symbol)
- {
- let side: MarketSide = (m.side === 'buy') ? MarketSide.Bid : MarketSide.Ask;
- this.orderBook.addEntry(side, m.price, Number(m.size));
- this.orderBook.refresh();
- }
- }
- }
- closeFeed()
- {
- throw new Error("Method not implemented.");
- }
- processUpdate()
- {
- throw new Error("Method not implemented.");
- }
- }
- export class BinanceDotNetFeed extends OrderBookFeed
- {
- constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook:OrderBook)
- {
- super(exchange,symbol, orderBook);
- console.log("Constructing Orderbook Feed");
- }
- loadBook()
- {
- throw new Error("Method not implemented.");
- }
- openFeed()
- {
- throw new Error("Method not implemented.");
- }
- closeFeed()
- {
- throw new Error("Method not implemented.");
- }
- processUpdate()
- {
- throw new Error("Method not implemented.");
- }
- }
- export class OrderBook implements IOrderBook
- {
- bids: Array<IOrderBookEntry>
- asks: Array<IOrderBookEntry>
- insideBid: IOrderBookEntry;
- insideAsk: IOrderBookEntry;
- spread: number;
- midPrice: number;
- previousMidPrice:number;
- originPrice:number;
- constructor(public exchange: ExchangeName, public symbol: InstrumentSymbol, public feed:IOrderBookFeed)
- {
- console.log("Constructing OrderBook");
- this.feed = this.createOderBookFeed();
- }
- protected createOderBookFeed(): OrderBookFeed
- {
- return null;
- }
- connect()
- {
- console.log("Opening Order Book Feed");
- this.feed.openFeed();
- }
- disconnect()
- {
- console.log("Closing Order Book Feed");
- this.feed.closeFeed();
- }
- clear()
- {
- throw new Error("Method not implemented.");
- }
- sort()
- {
- throw new Error("Method not implemented.");
- }
- getEntries(side: MarketSide): IOrderBookEntry[]
- {
- throw new Error("Method not implemented.");
- }
- getEntry(side: MarketSide, depth: number)
- {
- throw new Error("Method not implemented.");
- }
- addEntry(side: MarketSide, price: number, quantity: number)
- {
- //choose the correct array, based on the side of the market
- let array: IOrderBookEntry[] = (side === MarketSide.Bid) ? this.bids : this.asks;
- //see if we already have an entry at this price
- let i = array.findIndex((p: IOrderBookEntry) => p.price === price);
- //if we do have once and the incoming quantity is zero
- //we delete the element at that price.
- // if we have once and the quantity is more than zero
- // we update that entry's price.
- // If we don't have one at this price, we add a new entry
- if (i > -1 && quantity === 0.0) {
- array.splice(i, 1);
- } else if (i > -1) {
- array[i].quantity = quantity;
- } else if (quantity > 0.0) {
- // add to book
- array.push(new OrderBookEntry(this.symbol,side,price,quantity));
- }
- //sort only the array we modified
- if (side === MarketSide.Bid)
- array = array.sort(this.compareBids);
- else
- array = array.sort(this.compareAsks);
- //refresh derived data
- this.refresh();
- }
- //
- // Calculate values derived from the state of the order book
- // We call refresh() once after we load the book and then
- // once each time we add a new entry to the boo from the feed.
- //
- refresh()
- {
- this.insideBid = this.bids[0]
- this.insideAsk = this.asks[0];
- this.midPrice = Number(this.insideAsk.price- ( (this.insideAsk.price - this.insideBid.price) / 2 ));
- if (Math.abs(this.midPrice - this.previousMidPrice) >= 0.05)
- {
- this.previousMidPrice = this.midPrice;
- }
- if (this.originPrice === 0)
- {
- this.originPrice = this.midPrice;
- }
- }
- compareBids (a: any, b: any): number {
- return b.price - a.price;
- }
- compareAsks (a: any, b: any): number {
- return a.price - b.price;
- }
- }
- export class CryptoQuoteOrderBook extends OrderBook
- {
- protected createOderBookFeed(): OrderBookFeed
- {
- let feed:CryptoQuoteFeed = new CryptoQuoteFeed(this.exchange,this.symbol,this);
- return feed;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement