SHARE
TWEET

Untitled

GlobalLiquidity Mar 21st, 2019 59 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import { IExchangeOrder, IOrderBook, IOrderBookEntry, IOrderBookFeed } from "../3d/interfaces";
  2. import { MarketSide, OrderStatus, OrderSide, ExchangeName, InstrumentSymbol } from "./enums";
  3. import { disconnect } from "cluster";
  4.  
  5. export class OrderBookEntry implements IOrderBookEntry
  6. {
  7.     constructor(public symbol:InstrumentSymbol,
  8.                 public side: MarketSide,
  9.                 public price: number,
  10.                 public quantity: number)
  11.     {
  12.  
  13.     }
  14. }
  15.  
  16. export class OrderBookFeed implements IOrderBookFeed
  17. {
  18.     constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook: OrderBook)
  19.     {
  20.         console.log("Constructing Orderbook Feed");
  21.     }
  22.  
  23.     loadBook()
  24.     {
  25.         throw new Error("Implement in subclass");
  26.     }
  27.    
  28.     openFeed()
  29.     {
  30.         throw new Error("Implement in subclass");
  31.     }
  32.  
  33.     closeFeed()
  34.     {
  35.         throw new Error("Implement in subclass");
  36.     }
  37.  
  38.     processUpdate()
  39.     {
  40.         throw new Error("Implement in subclass");
  41.     }
  42. }
  43.  
  44. export class CryptoQuoteFeed extends OrderBookFeed
  45. {
  46.     private webSocket:WebSocket;
  47.     private feedUrl: string = 'wss://feed.cryptoquote.io';
  48.     private cryptoquoteKey: string = "e1983f70-a7e9-11e8-8362-5b2454c11240";
  49.  
  50.     constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook:OrderBook)
  51.     {
  52.         super(exchange,symbol, orderBook);
  53.         console.log("Constructing Orderbook Feed");
  54.     }
  55.  
  56.     createUrl(symbol: InstrumentSymbol, exchange: ExchangeName, interval: number) : string
  57.     {
  58.         let symbolString:string;
  59.         let exchangeString:string;
  60.  
  61.         switch(symbol)
  62.         {
  63.             case InstrumentSymbol.USD_BTC:
  64.                 symbolString = "BTCUSD";
  65.                 break;
  66.         }
  67.  
  68.         switch(exchange)
  69.         {
  70.             case ExchangeName.CryptoQuote:
  71.                 exchangeString = "Binance";
  72.                 break;
  73.         }
  74.        return `https://feed.cryptoquote.io/api/v1/book/${symbolString}.${exchangeString}/${interval}`;
  75.     }
  76.  
  77.     async loadBook(): Promise<void>
  78.     {
  79.         try {
  80.             const url: string = this.createUrl(this.symbol, this.exchange, 100);
  81.             console.log("Book Url: " + url);
  82.             const response: Response = await fetch(url);
  83.             const bData = await response.json();
  84.             bData.bids.forEach((bid: any) => {
  85.                 let entry:OrderBookEntry = new OrderBookEntry(this.symbol,
  86.                                                         MarketSide.Bid,
  87.                                                         bid[0],
  88.                                                         bid[1].size)                                      
  89.                 this.orderBook.bids.push(entry)
  90.             });
  91.  
  92.             this.orderBook.bids = this.orderBook.bids.sort(this.orderBook.compareBids);
  93.             bData.asks.forEach((ask: any) => {
  94.                 let entry:OrderBookEntry = new OrderBookEntry(this.symbol,
  95.                                                         MarketSide.Ask,
  96.                                                         ask[0],
  97.                                                         ask[1].size)                                      
  98.                 this.orderBook.asks.push(entry)
  99.             });
  100.  
  101.             this.orderBook.asks = this.orderBook.asks.sort(this.orderBook.compareAsks);
  102.             this.orderBook.refresh();
  103.         } catch (e) {
  104.             console.log('fetch error: ', e);
  105.         }
  106.     }
  107.    
  108.     openFeed()
  109.     {
  110.         this.webSocket = new WebSocket(`${this.feedUrl}/v1/firehose/${this.cryptoquoteKey}?services=book`);
  111.  
  112.         this.webSocket.onmessage = (event: any) => {
  113.             const m: any = JSON.parse(event.data);
  114.             if (m.updateType === 'book_update' && m.exchange.name === this.exchange && m.symbol === this.symbol)
  115.             {
  116.                 let side: MarketSide = (m.side === 'buy') ? MarketSide.Bid : MarketSide.Ask;
  117.  
  118.                 this.orderBook.addEntry(side, m.price, Number(m.size));
  119.                 this.orderBook.refresh();
  120.             }
  121.         }
  122.     }
  123.  
  124.     closeFeed()
  125.     {
  126.         throw new Error("Method not implemented.");
  127.     }
  128.  
  129.     processUpdate()
  130.     {
  131.         throw new Error("Method not implemented.");
  132.     }
  133. }
  134.  
  135. export class BinanceDotNetFeed extends OrderBookFeed
  136. {
  137.     constructor(public exchange:ExchangeName, public symbol:InstrumentSymbol, public orderBook:OrderBook)
  138.     {
  139.         super(exchange,symbol, orderBook);
  140.         console.log("Constructing Orderbook Feed");
  141.     }
  142.  
  143.     loadBook()
  144.     {
  145.         throw new Error("Method not implemented.");
  146.     }
  147.    
  148.     openFeed()
  149.     {
  150.         throw new Error("Method not implemented.");
  151.     }
  152.  
  153.     closeFeed()
  154.     {
  155.         throw new Error("Method not implemented.");
  156.     }
  157.  
  158.     processUpdate()
  159.     {
  160.         throw new Error("Method not implemented.");
  161.     }
  162. }
  163.  
  164. export class OrderBook implements IOrderBook
  165. {
  166.     bids: Array<IOrderBookEntry>
  167.     asks: Array<IOrderBookEntry>
  168.  
  169.     insideBid: IOrderBookEntry;
  170.     insideAsk: IOrderBookEntry;
  171.     spread: number;
  172.     midPrice: number;
  173.     previousMidPrice:number;
  174.     originPrice:number;
  175.  
  176.     constructor(public exchange: ExchangeName, public symbol: InstrumentSymbol, public feed:IOrderBookFeed)
  177.     {  
  178.         console.log("Constructing OrderBook");
  179.         this.feed = this.createOderBookFeed();
  180.     }
  181.  
  182.     protected createOderBookFeed(): OrderBookFeed
  183.     {
  184.         return null;
  185.     }
  186.  
  187.     connect()
  188.     {
  189.         console.log("Opening Order Book Feed");
  190.         this.feed.openFeed();
  191.     }
  192.  
  193.     disconnect()
  194.     {
  195.         console.log("Closing Order Book Feed");
  196.         this.feed.closeFeed();
  197.     }
  198.  
  199.     clear()
  200.     {
  201.         throw new Error("Method not implemented.");
  202.     }
  203.  
  204.     sort()
  205.     {
  206.         throw new Error("Method not implemented.");
  207.     }
  208.  
  209.     getEntries(side: MarketSide): IOrderBookEntry[]
  210.     {
  211.         throw new Error("Method not implemented.");
  212.     }
  213.  
  214.     getEntry(side: MarketSide, depth: number)
  215.     {
  216.         throw new Error("Method not implemented.");
  217.     }
  218.  
  219.     addEntry(side: MarketSide, price: number, quantity: number)
  220.     {
  221.         //choose the correct array, based on the side of the market
  222.         let array: IOrderBookEntry[] = (side === MarketSide.Bid) ? this.bids : this.asks;
  223.  
  224.         //see if we already have an entry at this price
  225.         let i = array.findIndex((p: IOrderBookEntry) => p.price === price);
  226.  
  227.         //if we do have once and the incoming quantity is zero
  228.         //we delete the element at that price.
  229.         // if we have once and the quantity is more than zero
  230.         // we update that entry's price.
  231.         // If we don't have one at this price, we add a new entry
  232.         if (i > -1 && quantity === 0.0) {
  233.             array.splice(i, 1);
  234.         } else if (i > -1) {
  235.             array[i].quantity = quantity;
  236.         } else if (quantity > 0.0) {
  237.             // add to book
  238.             array.push(new OrderBookEntry(this.symbol,side,price,quantity));
  239.         }
  240.  
  241.         //sort only the array we modified
  242.         if (side === MarketSide.Bid)
  243.             array = array.sort(this.compareBids);
  244.         else
  245.             array = array.sort(this.compareAsks);
  246.  
  247.         //refresh derived data
  248.         this.refresh();
  249.  
  250.     }
  251.  
  252.     //
  253.     // Calculate values derived from the state of the order book
  254.     // We call refresh() once after we load the book and then
  255.     // once each time we add a new entry to the boo from the feed.
  256.     //
  257.     refresh()
  258.     {
  259.         this.insideBid = this.bids[0]
  260.         this.insideAsk = this.asks[0];
  261.         this.midPrice = Number(this.insideAsk.price- ( (this.insideAsk.price - this.insideBid.price) / 2 ));
  262.    
  263.         if (Math.abs(this.midPrice - this.previousMidPrice) >= 0.05)
  264.         {
  265.             this.previousMidPrice = this.midPrice;
  266.         }
  267.  
  268.         if (this.originPrice === 0)
  269.         {
  270.             this.originPrice = this.midPrice;
  271.         }    
  272.     }
  273.    
  274.     compareBids (a: any, b: any): number {
  275.         return b.price - a.price;
  276.     }
  277.  
  278.     compareAsks (a: any, b: any): number {
  279.         return a.price - b.price;
  280.     }
  281. }
  282.  
  283. export class CryptoQuoteOrderBook extends OrderBook
  284. {
  285.     protected createOderBookFeed(): OrderBookFeed
  286.     {
  287.         let feed:CryptoQuoteFeed = new CryptoQuoteFeed(this.exchange,this.symbol,this);
  288.         return feed;
  289.     }
  290.  
  291. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top