def _updateOrder(self, lOrder): """ Identifies field based on B/S, alpha, numeric or decimal. Processes update as a cancel followed by a new order. """ dictOrderUpdate = dict(zip(orderKeys, lOrder[:len(orderKeys)])) # The unpolished code is to allow update of most fields if len(lOrder ) > len(orderKeys) - 1: # If there are any fields to update for n in lOrder[len(orderKeys):]: if n in BuySell: # If it is B/S, it is a side. dictOrderUpdate['side'] = n elif n.isalpha(): # If it is alpha, it is a ticker. dictOrderUpdate['ticker'] = n elif n.isdigit(): # If it is a int, it is a quantity. dictOrderUpdate['quantity'] = n else: # Else a price. dictOrderUpdate['price'] = n if dictOrderUpdate['orderId'] in self.orders: # If order exists orgOrder = self.orders[ dictOrderUpdate['orderId']] # fetch original order # Generate new order based based original order and updates order = Order(dictOrderUpdate['timestamp'], dictOrderUpdate['orderId'], dictOrderUpdate.get('ticker', None), dictOrderUpdate.get('side', None), dictOrderUpdate.get('price', None), dictOrderUpdate.get('quantity', None), orgOrder) self._cancelOrder(orgOrder) # Cancel original order self._addOrder(order) # Add new order else: # If order does not exists customValueError( 'orderId', dictOrderUpdate['orderId'], "Unable to amend order as it does not exist.")
def side(self, value): """ Set side attribute of order. Can be B for Buy or S for Sell only. """ if value in BuySell: self._side = value else: customValueError( 'side', value, 'B for Buy or S for Sell are the allowable values.')
def quantity(self, value): """ Set quantity attribute of order. Checks price is a float, positive and greater than zero (technicality). """ if int(value) > 0 and '.' not in str(value): self._quantity = int(value) else: customValueError( 'quantity', value, 'Quantity must be float, positive, a whole numeric and greater than ' 'zero.')
def price(self, value): """ Set price attribute of order. Checks price is a float, positive, greater than zero (technicality) and of 5dp or fewer. """ try: if float(value) > 0: if len(str(value).split('.')[1]) <= 5: self._price = float(value) else: raise ValueError else: raise ValueError except ValueError: customValueError( 'price', value, 'Price must be float, positive, of 5 decimal places or fewer ,' 'and greater than zero.')
def _cancelOrder(self, order): """ Remove order from orderBook (orders dict) """ if order: if order.orderId in self.orders: self._safeRemovePrice( self._identifyPriceDictionary(order.side), order.ticker, order.price) self.orders.pop(order.orderId) cancelOrder(self.db, order) else: # If order does not exists. One could consider ignoring it. customValueError( 'orderId', order.orderId, "Unable to cancel order as it does not exist.") else: # If order does not exists. One could consider ignoring it. customValueError('orderId', 'None', "Unable to cancel order as it does not exist.")
def processOrder(self, data): """ Processes orders based on action """ dictOrder = dict(zip(orderKeys, data.split('|'))) if dictOrder['action'] == 'a': dictOrderAdd = dict(zip(orderKeysAdd, data.split('|'))) order = Order(dictOrderAdd['timestamp'], dictOrderAdd['orderId'], dictOrderAdd['ticker'], dictOrderAdd['side'], dictOrderAdd['price'], dictOrderAdd['quantity']) self._addOrder(order) elif dictOrder['action'] == 'c': self._cancelOrder(self.orders.get(dictOrder['orderId'], None)) elif dictOrder['action'] == 'u': self._updateOrder(data.split('|')) else: customValueError('action', dictOrder['action'], "a, u and c are the allowable actions.")
def test_custom_value_error(): with pytest.raises(ValueError, match=r"Incorrect/invalid key with value value. More Error detail."): customValueError('key', 'value', 'More Error detail.')