def build_minimal_height_bst_bintrees(nums): # here SelfBalancingBST would be your implementaion of BST with self balancing property. # tree = SelfBalancingBST() tree = RBTree() for i in nums: tree.insert(i, i) return tree
def __init__(self): self.tree = RBTree() self.prices = dict() # { price : Queue } objects self.orders = dict() # { order_id : Order } objects self.volume = 0 # Contains total quantity from all Orders in tree self.num_orders = 0 # Contains count of Orders in tree self.depth = 0 # Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth)
def __init__(self): self.priceTree = RBTree() self.priceMap = {} # Map from price -> orderList object self.orderMap = {} # Order ID to Order object self.volume = 0 # How much volume on this side? self.nOrders = 0 # How many orders? self.lobDepth = 0 # How many different prices on lob?
def __init__(self, ticker, threshold): GDAX.OrderBook.__init__(self, product_id = ticker) self._threshold = threshold self._buyWhales = RBTree() self._sellWhales = RBTree() self._topBuyWhale = None self._topSellWhale = None
class RangeList(object): """List of ranges. Ranges are automatically merged and split when a new range is appended or removed. """ def __init__(self, sequence=None): self.tree = RBTree(sequence) def __iter__(self): return iter(self.tree.items()) def __repr__(self): return `list(self.tree.items())` def append(self, start, stop): """Append range (start, stop) to the list.""" if start >= stop: raise ValueError('stop has to be greater than start') delete = [] for nextstart, nextstop in self.tree[start:].items(): if nextstart <= stop: stop = max(nextstop, stop) delete.append(nextstart) else: break for key in delete: del self.tree[key] left = self.tree[:start] try: prevstart = max(left) prevstop = self.tree[prevstart] if prevstop >= start: start = prevstart stop = max(prevstop, stop) del self.tree[prevstart] except ValueError: pass self.tree[start] = stop def remove(self, start, stop): """Remove range (start, stop) from the list.""" delete = [] for nextstart, nextstop in self.tree[start:].items(): if nextstart < stop: if nextstop > stop: self.tree[stop] = nextstop delete.append(nextstart) else: break for key in delete: del self.tree[key] left = self.tree[:start] try: prevstart = max(left) prevstop = self.tree[prevstart] if prevstop > stop: self.tree[stop] = prevstop if prevstop >= start: self.tree[prevstart] = start except ValueError: pass
def __init__(self): self.price_tree = RBTree() self.price_map = {} # Dictionary containing price : std::list<std::shared_ptr<Order>> object self.order_map = {} # Dictionary containing order_id : Order object self.volume = 0 # Contains total quantity from all Orders in tree self.num_orders = 0 # Contains count of Orders in tree self.depth = 0 # Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth)
def process_snapshot(self, message: Dict): """ Process a snapshot message :param message: json """ # If a snapshot is sent reset trees self._asks = RBTree() self._bids = RBTree() # Parse all asks and add them to tree for ask in message['asks']: price, size = ask price = Decimal(price) size = Decimal(size) self._asks.insert(price, size) # Parse all bids and add them to tree for bid in message['bids']: price, size = bid price = Decimal(price) size = Decimal(size) self._bids.insert(price, size)
def __init__(self, endpoint="https://www.bitmex.com/api/v1", symbol='XBTUSD'): '''Connect to the websocket and initialize data stores.''' self.logger = logging.getLogger(__name__) self.logger.debug("Initializing WebSocket.") self.endpoint = endpoint self.symbol = symbol self.data = {} self.keys = {} self.exited = False self._asks = RBTree() self._bids = RBTree() # We can subscribe right in the connection querystring, so let's build that. # Subscribe to all pertinent endpoints wsURL = self.__get_url() self.logger.debug("Connecting to %s" % wsURL) self.__connect(wsURL, symbol) self.logger.info('Connected to WS, waiting for partials.') # Connected. Wait for partials self.__wait_for_symbol(symbol) self.logger.info('Got all market data. Starting.')
def __init__(self): self.price_tree = RBTree() self.price_map = {} # Dictionary containing price : OrderList object self.order_map = {} # Dictionary containing order_id : Order object self.volume = 0 # Contains total quantity from all Orders in tree self.num_orders = 0 # Contains count of Orders in tree self.depth = 0 # Number of different prices in tree
def __init__(self, product_id='BTC-USD', feed=None, log_to=None): self._product_id = product_id self._asks = RBTree() self._bids = RBTree() self._sequence = -1 self._current_ticker = None self._feed = feed
def reset_book(self): self._asks = RBTree() self._bids = RBTree() self.tref = datetime.datetime.now() # res = self._client.get_product_order_book(product_id=self.product_id, level=3) ################## params = {'level': 3} r = requests.get('https://api.gdax.com/products/{}/book'.format( self.product_id), params=params, timeout=30) try: res = r.json() except: res['bids'] = {} res['asks'] = {} res['sequence'] = 0 # r.raise_for_status() ################## for bid in res['bids']: self.add1({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add1({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence']
def __init__(self, product_id='BTC-USD'): print("Initializing order Book websocket for " + product_id) self.product = product_id super(GDaxBook, self).__init__(products=[self.product]) super(GDaxBook, self).start() self._asks = RBTree() self._bids = RBTree() self._client = PublicClient() self._sequence = -1 self._current_ticker = None
def __init__(self, product_id='BTC-USD', log_to=None): super(OrderBook, self).__init__(products=product_id) self._asks = RBTree() self._bids = RBTree() self._client = PublicClient() self._sequence = -1 self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None
def __init__(self, product_id, log_to=None): self._asks = RBTree() self._bids = RBTree() self._client = PublicClient() self._sequence = -1 self.sync = -1 self.product_id = product_id self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None
class Scope(object): # Static constants uses for indicating the result of the inserting # a symbol into the Scope. INSERT_SUCCESS = 0 INSERT_SHADOWED = 1 INSERT_REDECL = 2 # Initializes the Scope with a balanced Red-Black tree. def __init__(self): self.map = RBTree() # Inserts a symbol into the Scope. # # @return INSERT_SUCCESS or INSERT_REDECL. def insert(self, symbol): if not isinstance(symbol, Symbol): raise TypeError("'symbol' is not an instance of Symbol.") if symbol.identifier not in self.map: self.map[symbol.identifier] = symbol return Scope.INSERT_SUCCESS else: return Scope.INSERT_REDECL # Finds a symbol in the Scope. # # @param name String identifier for the Symbol to find. # # @return Symbol if found or None if not found. def find(self, name): return self.map.get(name, None) # Size of the scope. # # @return Number of Symbols in the Scope. def size(self): return len(self.map) # Clones the current Scope and returns a deep copy. # # @return Copy of the Scope. def clone(self): result = Scope() for identifier, value in self.map.items(): result.map[identifier] = value.clone() return result # @return String representation of the current Scope. def __repr__(self): symbols = [] for key, value in self.map.items(): symbols.append(' ' + key + ' : ' + repr(value)) return '\n'.join(symbols)
def __init__(self, product_id='BTC-USD'): print("Initializing order Book websocket for " + product_id) self.product = product_id super(GDaxBook, self).__init__(url="wss://ws-feed.pro.coinbase.com", products=[self.product], channels=["ticker"]) super(GDaxBook, self).start() self._asks = RBTree() self._bids = RBTree() self._client = PublicClient() self._sequence = -1 self._current_ticker = None
def on_message(self, message): if self._log_to: pickle.dump(message, self._log_to) sequence = message['sequence'] # initialize the order book from REST api if self._sequence == -1: self._asks = RBTree() self._bids = RBTree() res = self._client.get_product_order_book( product_id=self.product_id, level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': bid[0], 'size': bid[1] }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': ask[0], 'size': ask[1] }) self._sequence = res['sequence'] if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: print( 'Error: messages missing ({} - {}). Re-initializing websocket.' .format(sequence, self._sequence)) self.close() self.start() return msg_type = message['type'] if msg_type == 'open': self.add(message) # market orders will not have a remaining_size or price field as they are never on the open order book so we # ignore them. elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) self._current_ticker = message elif msg_type == 'change': self.change(message) self._sequence = sequence
def median_maintenance_rbtree(arr): median_sum = arr[0] rbtree = RBTree([(arr[0], 1)]) # (number, subtree_size) for i in range(1, len(arr)): ele = arr[i] rbtree.insert(ele, 1) post_order_traverse(rbtree._root) # assert rbtree._root.value == (i+1) median_order = int(i / 2) + 1 median_sum += select_order_statisic(rbtree._root, median_order) return median_sum
def __init__(self, product_id='BTC-USD', log_to=None, public_client=None): self._product_id = product_id self._asks = RBTree() self._bids = RBTree() if public_client is None: public_client = PublicGDAXClient() self._client = public_client self._sequence = -1 self._log_to = log_to if self._log_to: assert hasattr(self._log_to, 'write') self._current_ticker = None
def start(self, signal_q): authclient = authenticated_client.AuthenticatedClient( key=API_KEY, b64secret=API_SECRET, passphrase=API_PASS, api_url=API_URL) logging.basicConfig( filename='websock2.log', level=logging.DEBUG, format='%(asctime)s %(levelname)s %(name)s %(message)s') lock = threading.Lock() gv.lock = threading.Lock() gv._asks = RBTree() gv._bids = RBTree() gv.logger = logging.getLogger(__name__) gv.transactions_onbook = [] gv.market_price = None gv.sql_to_pandas = None gv.USD = None gv.crypto_balance = None signal_q = signal_q # bid_ask_q = Queue() M_get_depth = Queue() auth_user_msg_q = Queue() manager = Manager() M_bidask = manager.dict(({})) M_get_depth = manager.Value(ctypes.c_char_p, 'None') # print(M_bidask['bid']) logging.info('Start of Program') order_book = orderbook.OrderBook(API_KEY=API_KEY, API_SECRET=API_SECRET, API_PASS=API_PASS, API_URL=API_URL, WSS_URL=WSS_URL, products=products, M_bidask=M_bidask, authclient=authclient, auth_user_msg_q=auth_user_msg_q, M_get_depth=M_get_depth) order_book.start() print('started orderbook') orderwatch2 = orderwatch.orderwatch(M_bidask=M_bidask, signal_q=signal_q, auth_user_msg_q=auth_user_msg_q, M_get_depth=M_get_depth, products=products, authclient=authclient) orderwatch2.start() print('started orderwatch')
def onMessage(self, message): #Logging.logger.info(message) sequence = message['sequence'] if self._sequence == -1: self._asks = RBTree() self._bids = RBTree() res = self._client.getProductOrderBook(level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence'] if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: Logging.logger.error( 'Error: messages missing ({} - {}). Re-initializing websocket.' .format(sequence, self._sequence)) self.close() self.start() return msg_type = message['type'] if msg_type == 'open': self.add(message) elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) elif msg_type == 'change': self.change(message) self._sequence = sequence if not self.bookChanged is None: self.bookChanged()
def on_message(self, message): if self._log_to: pickle.dump(message, self._log_to) sequence = message['sequence'] if self._sequence == -1: self._asks = RBTree() self._bids = RBTree() res = self._client.get_product_order_book(level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence'] if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: print( 'Error: messages missing ({} - {}). Re-initializing websocket.' .format(sequence, self._sequence)) self.close() self.start() return msg_type = message['type'] if msg_type == 'open': self.add(message) elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) self._current_ticker = message elif msg_type == 'change': self.change(message) self._sequence = sequence
def __init__(self): WordCollection.word_tree = RBTree() with open('dictionary.txt', 'r', encoding='utf8') as file: WordCollection.word_list = file.readlines() for line in WordCollection.word_list: WordCollection.word_tree.insert(line.rstrip(), True)
def count_duplicates(lines): h, m = RBTree(), 0 for l in lines: if (l in h): h[l] += 1 else: h[l] = 1 if (m < h[l]): m = h[l] return h, m
def __init__(self, saveMessage=0, product_id='BTC-USD'): self.url = "wss://ws-feed.gdax.com/" self.ws = create_connection(self.url) self.product_id = product_id self.sequence = -1 self.stop = False self._sequence = -1 self._client = PublicClient() self._asks = RBTree() self._bids = RBTree() self._current_ticker = None self.saveMessage = saveMessage self.t1 = None self.t2 = None self.t3 = None
def __init__(self): ''' @summary: initialization of Ordertree class @mem price_tree: a red-black tree @mem price_map: Dictionary containing price : OrderList object @mem order_map: Dictionary containing order_id : Order object @mem volume: Contains total quantity from all Orders in tree @mem num_orders: Contains count of Orders in tree @mem depth: Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth) ''' self.price_tree = RBTree() self.price_map = {} self.order_map = {} self.volume = 0 self.num_orders = 0 self.depth = 0
def main(): ''' main ''' files = [] try: input_xml = parse_and_remove('/home/den/small_table_xml', 'route-information/route-table/rt') files.append(input_xml) except FileNotFoundError: pass try: ipv6_input_xml = parse_and_remove('/home/den/ipv6_xml', 'route-information/route-table/rt') files.append(ipv6_input_xml) except FileNotFoundError: pass tree = RBTree() prep = 'http://xml.juniper.net/junos/12.3R3/junos-routing' ns = XMLNamespaces(prep=prep) for file in files: create_tree(file, tree, prep, ns) send_update(tree)
def __init__(self): self.price_tree = RBTree() self.price_map = {} # Dictionary containing price : OrderList object self.order_map = {} # Dictionary containing order_id : Order object self.volume = 0 # Contains total quantity from all Orders in tree self.num_orders = 0 # Contains count of Orders in tree self.depth = 0 # Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth)
def __init__(self, delta=0.01, K=25, CX=1.1): self.delta = delta self.K = K self.CX = CX self.centroids = RBTree() self.nreset = 0 self.reset()
def example_centroids(): return RBTree([ (-1.1, Centroid(-1.1, 1)), (-0.5, Centroid(-0.5, 1)), (0.1, Centroid(0.1, 1)), (1.5, Centroid(1.5, 1)), ])
def identify_intersection_lines(L): sorted_line_details = sorted([LineDetail(l, True, l.x1 == l.x2) for l in L]) + \ sorted([LineDetail(l, False, l.x1 == l.x2) for l in L]) sorted_tree = RBTree() result = [] for line_detail in sorted_line_details: if not line_detail.is_start and not line_detail.is_perpendicular: del sorted_tree[line_detail.line.y1] elif line_detail.is_start and not line_detail.is_perpendicular: sorted_tree[line_detail.line.y1] = line_detail else: start, end = line_detail.line.y1, line_detail.line.y2 start, end = (start, end) if start < end else (end, start) intersects = [*sorted_tree.key_slice(start, end)] result.append(((line_detail.line.x1, line_detail.line.y1), intersects.copy())) return result
def __init__(self, rules): t = RBTree() ## to avoid exceptions during LE lookup t.insert(0, []) nets = [] for rule in rules: net = IPNetwork(rule.net) t.insert(net.first, []) t.insert(net.last+1, []) for prio, rule in enumerate(rules): net = IPNetwork(rule.net) for k,v in t.iter_items(net.first, net.last+1): v.append((prio, rule)) self.t = t
def on_message(self, message): sequence = message['sequence'] if self._sequence == -1: self._asks = RBTree() self._bids = RBTree() res = self._client.get_product_order_book(level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence'] if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: print('Error: messages missing ({} - {}). Re-initializing websocket.'.format(sequence, self._sequence)) self.close() self.start() return # print(message) msg_type = message['type'] if msg_type == 'open': self.add(message) elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) elif msg_type == 'change': self.change(message) self._sequence = sequence
def testADeleteRBT(tsize): from bintrees import RBTree from time import time from random import randint,sample TSIZE=tsize keys=sample(range(TSIZE*10), TSIZE) values=[0]*TSIZE mydata=list(zip(keys, values)) keystodel=sample(keys, 100);valdel=[0]*100 datadel=list(zip(keystodel, valdel)) mytree = RBTree() mytree.update(mydata) avgtime=0.0;times=100 for ii in range(times): startTime=time() for kd in keystodel: #mytree.pop(kd) del mytree[kd] avgtime+=(time()-startTime) mytree.update(datadel) avgtime=avgtime*1000.0/times print tsize,float(avgtime) return avgtime
class BrownianVariableHistory(object): ''' Represents the set of known time value pairs for a particular Brownian variable ''' def __init__(self): self._historyTree = RBTree() def insertData(self, t, val): ''' Inserts a data point into the history object t (float) : time val (float) : value ''' self._historyTree.insert(t, val) def getMartingaleRelevantPoints(self, t): ''' Returns 2 data points. The first will be the data point with the largest 't' in the history that is still smaller than the given user provided argument 't'. The second will be the datapoint with the smallest 't' that is still larger than the user provided 't'. If one or both of the data points do not exist, this function will return None in that data point's place. t (float) : time returns ((t1,val1), (t2,val2)) where t1, t2, val1, val2 are floats : 2 data points Ex: bh.getMartingaleRelevantPoints(3.1) == ((3.0, 0.07), (3.5, 0.21)) bh.getMartingaleRelevantPoints(3.6) == ((3.5, 0.21), None) ''' if self._historyTree.is_empty(): return None, None leftPoint = None rightPoint = None if self._historyTree.min_key() <= t: leftPoint = self._historyTree.floor_item(t) if self._historyTree.max_key() >= t: rightPoint = self._historyTree.ceiling_item(t) return leftPoint, rightPoint
def solve(par): n, days = par urn = RBTree() cost = 0 for d in days: for bill in d: try: urn[bill] += 1 except: urn[bill] = 1 if urn.count >= 2: m1, v1 = urn.max_item() m2, v2 = urn.min_item() if v1 == 1: urn.discard(m1) else: urn[m1] = v1 - 1 if v2 == 1: urn.discard(m2) else: urn[m2] = v2 - 1 cost += m1 - m2 return cost
def rb_build(): tree = RBTree.from_keys(keys)
from __main__ import rb_build_delete, rb_build, rb_search """ setup_FastRBTree = """ from __main__ import crb_build_delete, crb_build, crb_search """ try: fp = open('testkeys.txt') keys = eval(fp.read()) fp.close() bskeys = zip(keys, keys) except IOError: print("create 'testkeys.txt' with profile_bintree.py\n") sys.exit() py_searchtree = RBTree.from_keys(keys) cy_searchtree = FastRBTree.from_keys(keys) def rb_build_delete(): tree = RBTree.from_keys(keys) for key in keys: del tree[key] def crb_build_delete(): tree = FastRBTree.from_keys(keys) for key in keys: del tree[key]
tree[16.47] = 2694 tree[16.5] = 2079 tree[16.48] = 2599 tree[16.46] = 2564 tree[16.44] = 2709 # tree[16.45] = 2644 # tree[16.43] = 2621 # tree[16.49] = 3959 # tree[16.47] = 3494 # tree[16.48] = 3399 # tree[16.46] = 3364 # tree[16.44] = 3509 # tree[16.45] = 3444 # tree[16.43] = 3421 # tree[16.46] = 3735 # del tree[15.84] # tree[16.43] = 4921 # tree[16.48] = 4099 # tree[16.5] = 1279 # tree[16.49] = 1959 # tree[16.39] = tree.get(16.39,0) + 2000 rbt = RBTree() frbt = FastRBTree() populate(rbt) populate(frbt) print('RBT len: {0} FRBT len: {1}'.format(len(rbt), len(frbt))) for key, value in rbt.items(): print("RBTree[{key}] = {value} <-> FastRBTree[{key}] = {value2}".format(key=key, value=value, value2=frbt[key]))
class Exchange(Entity): def __init__(self, coin_type, price_type, bids=None, asks=None): self.coin_type = coin_type self.price_type = price_type self.bids = RBTree(bids or {}) self.asks = RBTree(asks or {}) def __eq__(self, other): return self.coin_type == other.coin_type and \ self.price_type == other.price_type and \ list(self.bids) == list(self.asks) @property def id(self): return "%s-%s" % (self.coin_type, self.price_type) def enqueue(self, order): rbtree = self._find_rbtree(order) queue = rbtree.setdefault(order.price, collections.deque()) queue.append(order.id) rbtree[order.price] = queue def dequeue(self, order): rbtree = self._find_rbtree(order) self._discard(rbtree, order.price, order.id) def dequeue_if_completed(self, order): if order.is_completed(): self.dequeue(order) def is_empty(self): return self.bids.is_empty() and self.asks.is_empty() # 最高买价大于等于最低卖价 def match(self, pop=False): bid_price, ask_price = None, None try: bid_price = self.bids.max_key() ask_price = self.asks.min_key() except ValueError: return (None, None) if bid_price >= ask_price: bids_queue = self.bids[bid_price] asks_queue = self.asks[ask_price] bid_id = bids_queue[0] ask_id = asks_queue[0] if pop: self._discard(self.bids, bid_price, bid_id) self._discard(self.asks, ask_price, ask_id) return (bid_id, ask_id) return (None, None) @classmethod def compute_deals(cls, bid, ask): assert type(bid) is BidOrder assert type(ask) is AskOrder assert bid.price >= ask.price assert bid.rest_amount > 0 assert ask.rest_amount > 0 timestamp = int(time.time()) # 卖出申报价格低于即时揭示的最高买入申报价格时,以即时揭示的最高买入申报价格为成交价。 # 买入申报价格高于即时揭示的最低卖出申报价格时,以即时揭示的最低卖出申报价格为成交价。 if bid.timestamp > ask.timestamp: deal_price = ask.price else: deal_price = bid.price # 这里需要 round(:down),不然会导致成交额大于委托额 deal_amount = min(bid.rest_amount, ask.rest_amount).quantize(PRECISION_EXP, ROUND_DOWN) ask_outcome = deal_amount bid_outcome_origin = (ask_outcome * deal_price).quantize(PRECISION_EXP, ROUND_DOWN) # 买单手续费 = 买单支出部分 * 买单手续费率,加在买单支出上 # 卖单手续费 = 卖单收入部分 * 卖单手续费率,扣在卖单收入里 bid_fee = (bid_outcome_origin * bid.fee_rate).quantize(PRECISION_EXP, ROUND_DOWN) ask_fee = (bid_outcome_origin * ask.fee_rate).quantize(PRECISION_EXP, ROUND_DOWN) bid_outcome = bid_outcome_origin + bid_fee # 买单收入 = 卖单支出 # 卖单收入 = 买单支出 - 卖单手续费 bid_income = ask_outcome ask_income = bid_outcome_origin - ask_fee # 记录订单未结清的额度 bid_rest_amount = bid.rest_amount - deal_amount ask_rest_amount = ask.rest_amount - deal_amount bid_rest_freeze_amount = bid.rest_freeze_amount - bid_outcome ask_rest_freeze_amount = ask.rest_freeze_amount - ask_outcome bid_deal = Deal(bid.id, ask.id, deal_price, deal_amount, bid_rest_amount, bid_rest_freeze_amount, bid_income, bid_outcome, bid_fee, timestamp) ask_deal = Deal(ask.id, bid.id, deal_price, deal_amount, ask_rest_amount, ask_rest_freeze_amount, ask_income, ask_outcome, ask_fee, timestamp) return (bid_deal, ask_deal) def match_and_compute_deals(self, repo): bid_id, ask_id = self.match() if not bid_id or not ask_id: return (None, None) bid = repo.orders.find(bid_id) ask = repo.orders.find(ask_id) return Exchange.compute_deals(bid, ask) def _find_rbtree(self, order): if order.exchange_id != self.id: raise ValueError("Order#exchange_id<%s> mismatch with Exchange<%s>" % (order.exchange_id, self.id)) if type(order) is BidOrder: return self.bids elif type(order) is AskOrder: return self.asks else: raise ValueError("argument is not an Order") # 当同价格的队列为空时,删除红黑树中的键 def _discard(self, rbtree, price, order_id): queue = rbtree.get(price) if not queue or not order_id in queue: return queue.remove(order_id) if queue == collections.deque(): del rbtree[price]
def __init__(self, sequence=None): self.tree = RBTree(sequence)
def rb_pop_max(): tree = RBTree.fromkeys(keys) while tree.count: tree.pop_max()
def __init__(self): self.map = RBTree()
print(seen) PrintUnique1(input) #1,5 #Code: Solution 2 (using using design #1 and red black tree) ''' Why red and black trees are better than hashtables? Source: http://www.quora.com/Why-would-anyone-like-to-use-a-red-black-tree-when-a-hash-table-can-do-the-job-perfectly 1. Simple memory management - simplifies error handling in concurrent code, less I/O hits, 2. Consistent performance because rehashing (expanding the hash table's array) happens on some insertions. This is important in real-time systems where you want to provide bounds on how long each operation takes 3. Keys are sorted ''' #https://bitbucket.org/mozman/bintrees from bintrees import RBTree def PrintUnique2(k,v): if (v == 1): #unique print(k) #print unique #Initialize tree = RBTree() #Insert for x in input: if (tree.get(x)): #duplicate tree.insert(x,tree.get(x)+1) #increment occurrence else: #new tree.insert(x,1) #Iterate tree.foreach(PrintUnique2,0) #0=inorder
''' Created on May 27, 2013 @author: Yubin Bai ''' from bintrees import RBTree infinity = (1 << 33) - 1 if __name__ == "__main__": tree = RBTree() tree[infinity] = 0 tree[-1 * infinity] = 0 print(tree.floor_item(0)) print(tree.ceiling_item(0))
from __main__ import keys, rb_prev, rb_succ """ setup_FastRBTree_ps = """ from __main__ import keys, crb_prev, crb_succ """ try: fp = open('testkeys.txt') keys = eval(fp.read()) fp.close() bskeys = zip(keys, keys) except IOError: print("create 'testkeys.txt' with profile_bintree.py\n") sys.exit() ptree = PTree.from_keys(keys) ftree = FTree.from_keys(keys) def rb_prev(): for key in keys: try: item = ptree.prev_item(key) except KeyError: pass def rb_succ(): for key in keys: try: item = ptree.succ_item(key)
def __init__(self, product_id='BTC-USD'): super(OrderBook, self).__init__(products=product_id) self._asks = RBTree() self._bids = RBTree() self._client = PublicClient(product_id=product_id) self._sequence = -1
def calc(arr, max_size): import heapq; print max_size nxt = arr[:]; pos = {}; for i in range(len(arr)): pos[arr[i]] = len(arr); for i in reversed(range(len(arr))): nxt[i] = pos[arr[i]]; pos[arr[i]] = i; print nxt; prio_queue = RBTree(); in_queue = {}; cache_miss = 0; cur_in_queue_cnt = 0; print arr; for i in range(len(arr)): out_str = str(i)+" "; print prio_queue; #cache missed if in_queue.has_key(arr[i]) == False: #while( space need): out_str += "Missed: "; cache_miss +=1; #add into cache if (cur_in_queue_cnt+1>max_size): del in_queue[prio_queue.min_item()[1]]; cur_in_queue_cnt-=1; out_str+= str(prio_queue.min_item()[1])+" is kicked. And "; prio_queue.discard(prio_queue.min_key()); out_str+= str(arr[i])+" is added into Q."; prio_queue.insert((-nxt[i],i),arr[i]); cur_in_queue_cnt+=1; in_queue[arr[i]] = 1; else : prio_queue.discard(prio_queue.ceiling_key((-i,0))); prio_queue.insert((-nxt[i],i),arr[i]); out_str += str(arr[i])+" hit."; print out_str; print cur_in_queue_cnt; #print prio_queue.q; print "Cache hit: "+str(len(arr)-cache_miss); print "Cache miss: "+str(cache_miss); print "Ratio: "+ str((len(arr)-cache_miss)*1.0/len(arr));
class OrderTree(object): '''A red-black tree used to store OrderLists in price order The exchange will be using the OrderTree to hold bid and ask data (one OrderTree for each side). Keeping the information in a red black tree makes it easier/faster to detect a match. ''' def __init__(self): self.price_tree = RBTree() self.price_map = {} # Dictionary containing price : OrderList object self.order_map = {} # Dictionary containing order_id : Order object self.volume = 0 # Contains total quantity from all Orders in tree self.num_orders = 0 # Contains count of Orders in tree self.depth = 0 # Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth) def __len__(self): return len(self.order_map) def get_price_list(self, price): return self.price_map[price] def get_order(self, order_id): return self.order_map[order_id] def create_price(self, price): self.depth += 1 # Add a price depth level to the tree new_list = OrderList() self.price_tree.insert(price, new_list) # Insert a new price into the tree self.price_map[price] = new_list # Can i just get this by using self.price_tree.get_value(price)? Maybe this is faster though. def remove_price(self, price): self.depth -= 1 # Remove a price depth level self.price_tree.remove(price) del self.price_map[price] def price_exists(self, price): return price in self.price_map def order_exists(self, order): return order in self.order_map def insert_order(self, quote): print quote if self.order_exists(quote['order_id']): self.remove_order_by_id(quote['order_id']) self.num_orders += 1 if quote['price'] not in self.price_map: self.create_price(quote['price']) # If price not in Price Map, create a node in RBtree order = Order(quote, self.price_map[quote['price']]) # Create an order self.price_map[order.price].append_order(order) # Add the order to the OrderList in Price Map self.order_map[order.order_id] = order self.volume += order.quantity def update_order(self, order_update): order = self.order_map[order_update['order_id']] original_quantity = order.quantity if order_update['price'] != order.price: # Price changed. Remove order and update tree. order_list = self.price_map[order.price] order_list.remove_order(order) if len(order_list) == 0: # If there is nothing else in the OrderList, remove the price from RBtree self.remove_price(order.price) self.insert_order(order_update) else: # Quantity changed. Price is the same. order.update_quantity(order_update['quantity'], order_update['timestamp']) self.volume += order.quantity - original_quantity def remove_order_by_id(self, order_id): self.num_orders -= 1 order = self.order_map[order_id] self.volume -= order.quantity order.order_list.remove_order(order) if len(order.order_list) == 0: self.remove_price(order.price) del self.order_map[order_id] def max_price(self): if self.depth > 0: return self.price_tree.max_key() else: return None def min_price(self): if self.depth > 0: return self.price_tree.min_key() else: return None def max_price_list(self): if self.depth > 0: return self.get_price_list(self.max_price()) else: return None def min_price_list(self): if self.depth > 0: return self.get_price_list(self.min_price()) else: return None
def __init__(self, coin_type, price_type, bids=None, asks=None): self.coin_type = coin_type self.price_type = price_type self.bids = RBTree(bids or {}) self.asks = RBTree(asks or {})
class OrderBook: def __init__(self, good, orderType=BID_ORDER): self.book = RBTree() self.orderType = orderType self.good = good """ getBest return the most competitive order in the book. This means the highest bid or the lowest ask """ def getBest(self): if len(self.book) == 0: return None if self.orderType == BID_ORDER: return self.book.max_key() else: return self.book.min_key() """ removeAllAgentOrders deletes all orders associated with this agent from this book """ def removeAllAgentOrders(self, agent): for order in self.book: if order.agent == agent: self.removeOrder(order) def removeOrder(self, order): return self.book.discard(order) """ getNext returns the next order to be executed (as determined by price and time) """ def getNext(self, order): if self.orderType == BID_ORDER: return self.book.prev_key(order) else: return self.book.succ_key(order) def addOrder(self, order): assert order.orderType == self.orderType, "Tried to add incorrect type of order to book" self.book[order] = True def addOrders(self, orders): for order in orders: self.addOrder(order) def printBook(self): for item in self.book.keys(): item.printOrder() print "-----------------------------" def size(self): return len(self.book) """ canMeet returns whether or not this order book can match any orders to orderToMatch, return orders that will meet it return tuple (quantity, list of orders) """ def canMeet(self, orderToMatch): assert orderToMatch.orderType != self.orderType, "Tried to meet incorrect order type " + \ orderToMatch.orderType quantity = 0 orders = [] canMeet = None # represents whether this orderbook can meet the order for order in self.book.keys(reverse=(self.orderType == BID_ORDER)): if quantity >= orderToMatch.quantity: break if ((order.price < orderToMatch.price and self.orderType == BID_ORDER) or (order.price > orderToMatch.price and self.orderType == ASK_ORDER)): break quantity += order.quantity if quantity > orderToMatch.quantity: quantityToKeep = quantity - orderToMatch.quantity else: quantityToKeep = order.quantity orders.append(order) if (quantity == orderToMatch.quantity): # Orders fit perfectly into this orderToMatch's quantity canMeet = "full" elif (quantity >= orderToMatch.quantity): # Order fit orderToMatch, but last order needs to be split canMeet = "full-split" elif quantity > 0: canMeet = "partial" # Only part of OrderToMatch could be filled else: canMeet = "nofill" # No order matched orderToMatch return canMeet, orders
class OrderBook(WebsocketClient): def __init__(self, product_id='BTC-USD'): super(OrderBook, self).__init__(products=product_id) self._asks = RBTree() self._bids = RBTree() self._client = PublicClient(product_id=product_id) self._sequence = -1 def on_message(self, message): sequence = message['sequence'] if self._sequence == -1: self._asks = RBTree() self._bids = RBTree() res = self._client.get_product_order_book(level=3) for bid in res['bids']: self.add({ 'id': bid[2], 'side': 'buy', 'price': Decimal(bid[0]), 'size': Decimal(bid[1]) }) for ask in res['asks']: self.add({ 'id': ask[2], 'side': 'sell', 'price': Decimal(ask[0]), 'size': Decimal(ask[1]) }) self._sequence = res['sequence'] if sequence <= self._sequence: # ignore older messages (e.g. before order book initialization from getProductOrderBook) return elif sequence > self._sequence + 1: print('Error: messages missing ({} - {}). Re-initializing websocket.'.format(sequence, self._sequence)) self.close() self.start() return # print(message) msg_type = message['type'] if msg_type == 'open': self.add(message) elif msg_type == 'done' and 'price' in message: self.remove(message) elif msg_type == 'match': self.match(message) elif msg_type == 'change': self.change(message) self._sequence = sequence # bid = self.get_bid() # bids = self.get_bids(bid) # bid_depth = sum([b['size'] for b in bids]) # ask = self.get_ask() # asks = self.get_asks(ask) # ask_depth = sum([a['size'] for a in asks]) # print('bid: %f @ %f - ask: %f @ %f' % (bid_depth, bid, ask_depth, ask)) def add(self, order): order = { 'id': order.get('order_id') or order['id'], 'side': order['side'], 'price': Decimal(order['price']), 'size': Decimal(order.get('size') or order['remaining_size']) } if order['side'] == 'buy': bids = self.get_bids(order['price']) if bids is None: bids = [order] else: bids.append(order) self.set_bids(order['price'], bids) else: asks = self.get_asks(order['price']) if asks is None: asks = [order] else: asks.append(order) self.set_asks(order['price'], asks) def remove(self, order): price = Decimal(order['price']) if order['side'] == 'buy': bids = self.get_bids(price) if bids is not None: bids = [o for o in bids if o['id'] != order['order_id']] if len(bids) > 0: self.set_bids(price, bids) else: self.remove_bids(price) else: asks = self.get_asks(price) if asks is not None: asks = [o for o in asks if o['id'] != order['order_id']] if len(asks) > 0: self.set_asks(price, asks) else: self.remove_asks(price) def match(self, order): size = Decimal(order['size']) price = Decimal(order['price']) if order['side'] == 'buy': bids = self.get_bids(price) if not bids: return assert bids[0]['id'] == order['maker_order_id'] if bids[0]['size'] == size: self.set_bids(price, bids[1:]) else: bids[0]['size'] -= size self.set_bids(price, bids) else: asks = self.get_asks(price) if not asks: return assert asks[0]['id'] == order['maker_order_id'] if asks[0]['size'] == size: self.set_asks(price, asks[1:]) else: asks[0]['size'] -= size self.set_asks(price, asks) def change(self, order): new_size = Decimal(order['new_size']) price = Decimal(order['price']) if order['side'] == 'buy': bids = self.get_bids(price) if bids is None or not any(o['id'] == order['order_id'] for o in bids): return index = map(itemgetter('id'), bids).index(order['order_id']) bids[index]['size'] = new_size self.set_bids(price, bids) else: asks = self.get_asks(price) if asks is None or not any(o['id'] == order['order_id'] for o in asks): return index = map(itemgetter('id'), asks).index(order['order_id']) asks[index]['size'] = new_size self.set_asks(price, asks) tree = self._asks if order['side'] == 'sell' else self._bids node = tree.get(price) if node is None or not any(o['id'] == order['order_id'] for o in node): return def get_current_book(self): result = { 'sequence': self._sequence, 'asks': [], 'bids': [], } for ask in self._asks: try: # There can be a race condition here, where a price point is removed # between these two ops this_ask = self._asks[ask] except KeyError: continue for order in this_ask: result['asks'].append([order['price'], order['size'], order['id']]) for bid in self._bids: try: # There can be a race condition here, where a price point is removed # between these two ops this_bid = self._bids[bid] except KeyError: continue for order in this_bid: result['bids'].append([order['price'], order['size'], order['id']]) return result def get_ask(self): return self._asks.min_key() def get_asks(self, price): return self._asks.get(price) def remove_asks(self, price): self._asks.remove(price) def set_asks(self, price, asks): self._asks.insert(price, asks) def get_bid(self): return self._bids.max_key() def get_bids(self, price): return self._bids.get(price) def remove_bids(self, price): self._bids.remove(price) def set_bids(self, price, bids): self._bids.insert(price, bids)
def __init__(self, good, orderType=BID_ORDER): self.book = RBTree() self.orderType = orderType self.good = good
class OrderTree(object): ''' An RBtree used to store OrderLists in price order ''' def __init__(self): ''' @summary: initialization of Ordertree class @mem price_tree: a red-black tree @mem price_map: Dictionary containing price : OrderList object @mem order_map: Dictionary containing order_id : Order object @mem volume: Contains total quantity from all Orders in tree @mem num_orders: Contains count of Orders in tree @mem depth: Number of different prices in tree (http://en.wikipedia.org/wiki/Order_book_(trading)#Book_depth) ''' self.price_tree = RBTree() self.price_map = {} self.order_map = {} self.volume = 0 self.num_orders = 0 self.depth = 0 def __len__(self): ''' return the length of order_map ''' return len(self.order_map) def get_price_list(self, price): ''' get the price list from the price map ''' return self.price_map[price] def get_order(self, order_id): ''' get order list from order map ''' return self.order_map[order_id] def create_price(self, price): ''' create a new price if adding an order without price in the tree ''' self.depth += 1 new_list = OrderList() self.price_tree.insert(price, new_list) self.price_map[price] = new_list def remove_price(self, price): ''' remove a price from the tree ''' self.depth -= 1 self.price_tree.remove(price) del self.price_map[price] def price_exists(self, price): ''' check whether price exists in price map ''' return price in self.price_map def order_exists(self, order): ''' check whether an order exists in order map ''' return order in self.order_map def insert_order(self, quote): ''' insert an order into the order map ''' if self.order_exists(quote['order_id']): self.remove_order_by_id(quote['order_id']) self.num_orders += 1 if quote['price'] not in self.price_map: self.create_price(quote['price']) # If price not in Price Map, create a node in RBtree order = Order(quote, self.price_map[quote['price']]) # Create an order self.price_map[order.price].append_order(order) # Add the order to the OrderList in Price Map self.order_map[order.order_id] = order self.volume += order.quantity def remove_order_by_id(self, order_id): ''' remove an order from the order map ''' self.num_orders -= 1 order = self.order_map[order_id] self.volume -= order.quantity order.order_list.remove_order(order) if len(order.order_list) == 0: self.remove_price(order.price) del self.order_map[order_id] def max_price(self): ''' return max price in price tree ''' if self.depth > 0: return self.price_tree.max_key() else: return None def min_price(self): ''' return min price in price tree ''' if self.depth > 0: return self.price_tree.min_key() else: return None def max_price_list(self): ''' return max price in price tree ''' if self.depth > 0: return self.get_price_list(self.max_price()) else: return None def min_price_list(self): ''' return min price in price tree ''' if self.depth > 0: return self.get_price_list(self.min_price()) else: return None
def __init__(self): self._historyTree = RBTree()
def rb_build_delete(): tree = RBTree.from_keys(keys) for key in keys: del tree[key]