def __init__(self, order_id, price, quantity, timeout, timestamp, is_ask): """ :param order_id: An order id to identify the order :param price: A price to indicate for which amount to sell or buy :param quantity: A quantity to indicate how much to sell or buy :param timeout: A timeout when this tick is going to expire :param timestamp: A timestamp when the order was created :param is_ask: A bool to indicate if this order is an ask :type order_id: OrderId :type price: Price :type quantity: Quantity :type timeout: Timeout :type timestamp: Timestamp :type is_ask: bool """ super(Order, self).__init__() self._logger = logging.getLogger(self.__class__.__name__) assert isinstance(order_id, OrderId), type(order_id) assert isinstance(price, Price), type(price) assert isinstance(quantity, Quantity), type(quantity) assert isinstance(timeout, Timeout), type(timeout) assert isinstance(timestamp, Timestamp), type(timestamp) assert isinstance(is_ask, bool), type(is_ask) self._order_id = order_id self._price = price self._quantity = quantity self._reserved_quantity = Quantity(0) self._traded_quantity = Quantity(0) self._timeout = timeout self._timestamp = timestamp self._completed_timestamp = None self._is_ask = is_ask self._reserved_ticks = {}
def _search_for_quantity_in_price_level_total(self, tick_entry, quantity_to_trade, order): if tick_entry.quantity <= Quantity(0): return quantity_to_trade, [] trading_quantity = quantity_to_trade quantity_to_trade = Quantity(0) self._logger.debug("Match with the id (%s) was found for order (%s). Price: %i, Quantity: %i)", str(tick_entry.order_id), str(order.order_id), int(tick_entry.price), int(trading_quantity)) reserved = order.reserve_quantity_for_tick(tick_entry.tick.order_id, trading_quantity) if not reserved: # Error happened self._logger.warn("Something went wrong") return self._search_for_quantity_in_price_level(tick_entry.next_tick(), quantity_to_trade, order) proposed_trades = [Trade.propose( self.order_book.message_repository.next_identity(), order.order_id, tick_entry.order_id, tick_entry.price, trading_quantity, Timestamp.now() )] return quantity_to_trade, proposed_trades
def trade_tick(self, order_id, recipient_order_id, quantity): """ :type order_id: OrderId :type recipient_order_id: OrderId :type quantity: Quantity """ assert isinstance(order_id, OrderId), type(order_id) assert isinstance(recipient_order_id, OrderId), type(recipient_order_id) assert isinstance(quantity, Quantity), type(quantity) self._logger.debug("Trading tick in order book for own order %s vs order %s", str(order_id), str(recipient_order_id)) if self.bid_exists(order_id): tick = self.get_bid(order_id) tick.quantity -= quantity if tick.quantity == Quantity(0): self.remove_tick(tick.order_id) if self.ask_exists(order_id): tick = self.get_ask(order_id) tick.quantity -= quantity if tick.quantity == Quantity(0): self.remove_tick(tick.order_id) if self.bid_exists(recipient_order_id): tick = self.get_bid(recipient_order_id) tick.quantity -= quantity if tick.quantity == Quantity(0): self.remove_tick(tick.order_id) if self.ask_exists(recipient_order_id): tick = self.get_ask(recipient_order_id) tick.quantity -= quantity if tick.quantity == Quantity(0): self.remove_tick(tick.order_id)
def test_isStateValid_multiRelation_valid(self): state = { "B": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "C": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, } relations = [ { "type": "EX", "args": None, "Q1": ("B", "Q"), "Q2": ("B", "Q"), }, { "type": "I-", "args": None, "Q1": ("C", "Q"), "Q2": ("B", "Q"), }, { "type": "P+", "args": None, "Q1": ("B", "Q"), "Q2": ("C", "Q"), }, ] self.assertEqual(isStateValid(state, relations), True)
def determine_incremental_quantity_list(total_quantity): """ Determines an incremental quantity list :type total_quantity: Quantity :return: Incremental quantity list :rtype: List[Quantity] """ # Check whether we should change the INCREMENTAL_QUANTITY to avoid not going over our MAX transactions quantity_per_trade = IncrementalQuantityManager.INCREMENTAL_QUANTITY if quantity_per_trade * IncrementalQuantityManager.MAX_TRANSACTIONS < int(total_quantity): quantity_per_trade = int(total_quantity) / IncrementalQuantityManager.MAX_TRANSACTIONS incremental_quantities = [] remaining_quantity = int(total_quantity) if remaining_quantity > 0: initial_quantity = min(IncrementalQuantityManager.INITIAL_QUANTITY, remaining_quantity) incremental_quantities.append(Quantity(initial_quantity)) remaining_quantity -= initial_quantity while remaining_quantity > 0: incremental_quantity = min(quantity_per_trade, remaining_quantity) incremental_quantities.append(Quantity(incremental_quantity)) remaining_quantity -= incremental_quantity return incremental_quantities
def test_isStateValid_relationOrder(self): state = { "A": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.ZERO)) }, "B": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "C": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.ZERO)) }, } relations = [ { "type": "I+", "args": None, "Q1": ("A", "Q"), "Q2": ("B", "Q"), }, { "type": "I-", "args": None, "Q1": ("C", "Q"), "Q2": ("B", "Q"), }, { "type": "P+", "args": None, "Q1": ("B", "Q"), "Q2": ("C", "Q"), }, ] self.assertEqual(isStateValid(state, relations), False)
def test_p_plus_change_positive(self): q1 = Quantity(None, Derivative(DValue.PLUS)) q2 = Quantity(None, Derivative(DValue.ZERO)) r.propotionalPositive(q1, q2) self.assertEqual(q2.derivative.value, DValue.PLUS)
def _unit_class_mul(self, other): """Multiply a Unit by an object. If other is another Unit, returns a new composite Unit. Exponents of similar dimensions are added. If self and other share similar BaseDimension, but with different BaseUnits, the resulting BaseUnit for that BaseDimension will be that used in self. If other is a not another Unit, this method returns a new Quantity... UNLESS other is a Quantity and the resulting unit is dimensionless, in which case the underlying value type of the Quantity is returned. """ if is_unit(other): if self in Unit._multiplication_cache: if other in Unit._multiplication_cache[self]: return Unit._multiplication_cache[self][other] else: Unit._multiplication_cache[self] = {} # print "unit * unit" result1 = { } # dictionary of dimensionTuple: (BaseOrScaledUnit, exponent) for unit, exponent in self.iter_base_or_scaled_units(): d = unit.get_dimension_tuple() if d not in result1: result1[d] = {} assert unit not in result1[d] result1[d][unit] = exponent for unit, exponent in other.iter_base_or_scaled_units(): d = unit.get_dimension_tuple() if d not in result1: result1[d] = {} if unit not in result1[d]: result1[d][unit] = 0 result1[d][unit] += exponent result2 = {} # stripped of zero exponents for d in result1: for unit in result1[d]: exponent = result1[d][unit] if exponent != 0: assert unit not in result2 result2[unit] = exponent new_unit = Unit(result2) Unit._multiplication_cache[self][other] = new_unit return new_unit elif is_quantity(other): # print "unit * quantity" value = other._value unit = self * other.unit return Quantity(value, unit).reduce_unit(self) else: # print "scalar * unit" value = other unit = self # Is reduce_unit needed here? I hope not, there is a performance issue... # return Quantity(other, self).reduce_unit(self) return Quantity(other, self)
def balance(self): """ :rtype: Quantity """ total = self.multi_chain_community.persistence.get_total(self.public_key) if total == (-1, -1): return Quantity(0) else: return Quantity(int(max(0, total[0] - total[1]) / 2))
def test_p_plus_copy_value(self): q1 = Quantity(None, Derivative(DValue.PLUS)) q2 = Quantity(None, Derivative(DValue.ZERO)) # apply proportion relation r.propotionalPositive(q1, q2) self.assertEqual(q2.derivative.value, DValue.PLUS) # change q1 derivative without affecting q2 derivative q1.derivative.value = DValue.MINUS self.assertEqual(q2.derivative.value, DValue.PLUS)
def test_isStateValid_multiRelation_sameTail_ambiguous(self): state1 = { "A": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "B": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "C": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.ZERO)) }, } state2 = { "A": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "B": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.ZERO)) }, "C": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.ZERO)) }, } state3 = { "A": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.MINUS)) }, "B": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.PLUS)) }, "C": { "Q": Quantity(Magnitude(MValue.PLUS), Derivative(DValue.ZERO)) }, } relations = [ { "type": "EX", "args": None, "Q1": ("A", "Q"), "Q2": ("A", "Q"), }, { "type": "P+", "args": None, "Q1": ("A", "Q"), "Q2": ("B", "Q"), }, { "type": "I+", "args": None, "Q1": ("C", "Q"), "Q2": ("B", "Q"), }, ] self.assertEqual(isStateValid(state1, relations), True) self.assertEqual(isStateValid(state2, relations), True) self.assertEqual(isStateValid(state3, relations), True)
def generate(): magnitudes = list(map(int, MagnitudeValues)) derivatives = list(map(int, DerivativeValues)) state = State(0) state.quantities = { # ASSUMPTION: Inflow has no MAX "Inflow": (magnitudes[:2], derivatives), "Volume": (magnitudes, derivatives), "Outflow": (magnitudes, derivatives), } states = [] temp = [] for s in state.quantities: temp.extend(state.quantities[s]) prod = product(*temp) for p in prod: idx = 0 new_state = State(len(states)) for s in state.quantities: new_state.quantities[s] = {} mag_bound = state.quantities[s][0][-1] q = Quantity(Magnitude(p[idx], maximum=mag_bound), Derivative(p[idx + 1])) new_state.quantities[s] = q idx += 2 states.append(new_state) return states
def __init__(self): self._price_level_list = PriceLevelList( ) # Sorted list containing dictionary with price levels: Price -> PriceLevel self._price_map = {} # Map: Price -> PriceLevel self._tick_map = {} # Map: MessageId -> TickEntry self._volume = Quantity( 0) # Total number of quantity contained in all the price levels self._depth = 0 # Total amount of price levels
def over_generate(blue_print=None, mag_Enum=MValue, der_Enum=DValue): """generates all combinations of states. Assumes that all quantities have the can take the same magnetude and derivative values. Input: blue_print: dict(dict: (list, list))) defining the state and the values it can take. mag_Enum: IntEnum with the possible values for magntudes. der_Enum: IntEnum with the possible values for derivatives. Output: list(states) all possible states. """ #defaut state blueprint in case none is given. if blue_print == None: mags = list(map(int, mag_Enum)) ders = list(map(int, der_Enum)) blue_print = { "Hoose": { "Inflow": ([0, 1], ders) }, "Container": { "Volume": (mags, ders) }, "Drain": { "Outflow": (mags, ders) }, } #Creates all states states = [] t = [] for e in blue_print: for q in blue_print[e]: t.append(blue_print[e][q][0]) t.append(blue_print[e][q][1]) t = tuple(t) combs = list(product(*t)) for c in combs: idx = 0 state = {} for e in blue_print: state[e] = {} for q in blue_print[e]: mag_bound = blue_print[e][q][0][-1] state[e][q] = Quantity(Magnitude(c[idx], upperBound=mag_bound), Derivative(c[idx + 1])) idx += 2 states.append(state) return states
def rng(self): self.size.rng() self.unit.rng() arr = np.random.random(size=self.size.value) * (self.ub - self.lb) + self.lb arr *= self.unit.conversion_factor arr = prec_round(arr, self.precision) del self.value self.value = Quantity(arr, self.unit.value)
def test_isStateValid_noEX(self): state = { "A": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.PLUS)) } } relations = [] self.assertEqual(isStateValid(state, relations), False)
def test_isStateValid_singleRelation_valid(self): state = { "B": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.ZERO)) }, "C": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.ZERO)) }, } relations = [ { "type": "P+", "args": None, "Q1": ("B", "Q"), "Q2": ("C", "Q"), }, ] self.assertEqual(isStateValid(state, relations), True)
def getNminiAODEvts(self, rootfile): quantity = Quantity(name_nano='genEventCount', name_flat='geneventcount', nbins=100, bin_min=1, bin_max=1e9) hist = self.createHisto(rootfile=rootfile, tree_name='run_tree', quantity=quantity) n_reco_evts = hist.GetMean() * hist.GetEntries() return n_reco_evts
def test_isStateValid_lower_boundary_derivatives(self): state_invalid = { "A": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.MINUS)) }, } state_valid = { "A": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.PLUS)) }, } relations = [{ "type": "EX", "args": None, "Q1": ("A", "Q"), "Q2": ("A", "Q"), }] self.assertEqual(isStateValid(state_invalid, relations), False) self.assertEqual(isStateValid(state_valid, relations), True)
def add_trade(self, other_order_id, quantity): self._logger.debug("Adding trade for order %s with quantity %s (other id: %s)", str(self.order_id), quantity, str(other_order_id)) self._traded_quantity += quantity try: self.release_quantity_for_tick(other_order_id) except TickWasNotReserved: pass assert self.available_quantity >= Quantity(0) if self.is_complete(): self._completed_timestamp = Timestamp.now()
def test_getRelationQuantities(self): state = { "B": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.PLUS)) }, "C": { "Q": Quantity(Magnitude(MValue.ZERO), Derivative(DValue.ZERO)) }, } relation = { "type": "P+", "args": None, "Q1": ("B", "Q"), "Q2": ("C", "Q"), } head, tail = getRelationQuantities(state, relation) self.assertEqual( head, Quantity(Magnitude(MValue.ZERO), Derivative(DValue.PLUS))) self.assertEqual( tail, Quantity(Magnitude(MValue.ZERO), Derivative(DValue.ZERO)))
def _match_bid(self, order): proposed_trades = [] quantity_to_trade = order.available_quantity if order.price >= self.order_book.ask_price and quantity_to_trade > Quantity(0): # Scan the price levels in the order book quantity_to_trade, proposed_trades = self._search_for_quantity_in_order_book( self.order_book.ask_price, self.order_book.ask_price_level, quantity_to_trade, order) return quantity_to_trade, proposed_trades
def computeBkgYieldsFromABCDQCDMC(self): ''' Estimate background yields from data using the ABCD method A = b_mass < 6.27 && hnl_charge == 0 (SR) B = b_mass < 6.27 && hnl_charge != 0 C = b_mass > 6.27 && hnl_charge == 0 D = b_mass > 6.27 && hnl_charge != 0 N_A = N_B * N_C/N_D ''' quantity = Quantity(name_flat='hnl_mass', nbins=1, bin_min=0, bin_max=1000) bin_selection = self.selection hist_mc_tot_A = self.getHistoMC(quantity=quantity, selection=self.selection+' && b_mass<6.27 && hnl_charge==0') hist_mc_tot_B = self.getHistoMC(quantity=quantity, selection=self.selection+' && b_mass<6.27 && hnl_charge!=0') hist_mc_tot_C = self.getHistoMC(quantity=quantity, selection=self.selection+' && b_mass>6.27 && hnl_charge==0') hist_mc_tot_D = self.getHistoMC(quantity=quantity, selection=self.selection+' && b_mass>6.27 && hnl_charge!=0') #hist_mc_tot_A = self.getHistoMC(quantity=quantity, selection='b_mass<6.27 && hnl_charge==0') #hist_mc_tot_A = self.getHistoMC(quantity=quantity, selection='sv_prob>0.05 && hnl_charge==0') #hist_mc_tot_A = self.getHistoMC(quantity=quantity, selection='b_mass<6.27 && hnl_mass<5.4') #hist_mc_tot_B = self.getHistoMC(quantity=quantity, selection='b_mass<6.27 && hnl_charge!=0') #hist_mc_tot_B = self.getHistoMC(quantity=quantity, selection='sv_prob>0.05 && hnl_charge!=0') #hist_mc_tot_B = self.getHistoMC(quantity=quantity, selection='b_mass<6.27 && hnl_mass>5.4') #hist_mc_tot_C = self.getHistoMC(quantity=quantity, selection='b_mass>6.27 && hnl_charge==0') #hist_mc_tot_C = self.getHistoMC(quantity=quantity, selection='sv_prob<0.05 && hnl_charge==0') #hist_mc_tot_C = self.getHistoMC(quantity=quantity, selection='b_mass>6.27 && hnl_mass<5.4') #hist_mc_tot_D = self.getHistoMC(quantity=quantity, selection='b_mass>6.27 && hnl_charge!=0') #hist_mc_tot_D = self.getHistoMC(quantity=quantity, selection='sv_prob<0.05 && hnl_charge!=0') #hist_mc_tot_D = self.getHistoMC(quantity=quantity, selection='b_mass>6.27 && hnl_mass>5.4') n_obs_mc_A = hist_mc_tot_A.GetBinContent(1) n_obs_mc_B = hist_mc_tot_B.GetBinContent(1) n_obs_mc_C = hist_mc_tot_C.GetBinContent(1) n_obs_mc_D = hist_mc_tot_D.GetBinContent(1) n_err_mc_A = hist_mc_tot_A.GetBinError(1) #math.sqrt(n_obs_mc_A) n_err_mc_B = hist_mc_tot_B.GetBinError(1) #math.sqrt(n_obs_mc_B) n_err_mc_C = hist_mc_tot_C.GetBinError(1) #math.sqrt(n_obs_mc_C) n_err_mc_D = hist_mc_tot_D.GetBinError(1) #math.sqrt(n_obs_mc_D) n_obs_mc_A = n_obs_mc_B * (n_obs_mc_C / n_obs_mc_D) n_err_mc_A = n_obs_mc_A * (n_err_mc_B / n_obs_mc_B + n_err_mc_C / n_obs_mc_C + n_err_mc_D / n_obs_mc_D) n_real_mc_A = hist_mc_tot_A.GetBinContent(1) n_realerr_mc_A = hist_mc_tot_A.GetBinError(1) print 'ABCD estimation SR: {} +- {}'.format(int(n_obs_mc_A), int(n_err_mc_A)) print 'True SR: {} +- {}'.format(int(n_real_mc_A), int(n_realerr_mc_A))
def release_quantity_for_tick(self, order_id): """ :param order_id: The order id from another peer that the quantity needs to be released for :type order_id: OrderId :raises TickWasNotReserved: Thrown when the tick was not reserved first """ if order_id in self._reserved_ticks: self._logger.debug("Releasing quantity for order id %s (own order id: %s), total quantity: %s, traded: %s", str(order_id), str(self.order_id), self.total_quantity, self.traded_quantity) if self._reserved_quantity >= self._reserved_ticks[order_id]: self._reserved_quantity -= self._reserved_ticks[order_id] assert self.available_quantity >= Quantity(0) del self._reserved_ticks[order_id] else: raise TickWasNotReserved()
def _unit_class_rdiv(self, other): """ Divide another object type by a Unit. Returns a new Quantity with a value of other and units of the inverse of self. """ if is_unit(other): raise NotImplementedError( 'programmer is surprised __rtruediv__ was called instead of __truediv__' ) else: # print "R scalar / unit" unit = pow(self, -1.0) value = other return Quantity(value, unit).reduce_unit(self)
def match_order(self, order): """ :param order: The order to match against :type order: Order :return: The proposed trades :rtype: [ProposedTrade] """ assert isinstance(order, Order), type(order) if order.is_ask(): quantity_to_trade, proposed_trades = self._match_ask(order) else: quantity_to_trade, proposed_trades = self._match_bid(order) if quantity_to_trade > Quantity(0): self._logger.debug("Quantity not matched: %i", int(quantity_to_trade)) return proposed_trades
def _search_for_quantity_in_price_level(self, tick_entry, quantity_to_trade, order): """ Search through the tick entries in the price levels :param tick_entry: The tick entry to match against :param quantity_to_trade: The quantity still to be matched :param order: The order to match for :type tick_entry: TickEntry :type quantity_to_trade: Quantity :type order: Order :return: The quantity to trade and the proposed trades :rtype: Quantity, [ProposedTrade] """ if tick_entry is None: # Last tick return quantity_to_trade, [] if tick_entry.quantity <= Quantity(0): return quantity_to_trade, [] # Check if order and tick entry have the same trader id / origin if order.order_id.trader_id == tick_entry.order_id.trader_id: return quantity_to_trade, [] assert isinstance(tick_entry, TickEntry), type(tick_entry) assert isinstance(quantity_to_trade, Quantity), type(quantity_to_trade) assert isinstance(order, Order), type(order) if tick_entry.order_id in order.reserved_ticks: # Tick is already reserved for this order return self._search_for_quantity_in_price_level(tick_entry.next_tick(), quantity_to_trade, order) if not tick_entry.is_valid(): # Tick is time out or reserved return self._search_for_quantity_in_price_level(tick_entry.next_tick(), quantity_to_trade, order) if quantity_to_trade <= tick_entry.quantity: # All the quantity can be matched in this tick quantity_to_trade, proposed_trades = self._search_for_quantity_in_price_level_total(tick_entry, quantity_to_trade, order) else: # Not all the quantity can be matched in this tick quantity_to_trade, proposed_trades = self._search_for_quantity_in_price_level_partial(tick_entry, quantity_to_trade, order) return quantity_to_trade, proposed_trades
def getSignalEfficiency(self): ''' eff(bin) = N_flat(bin) / N_gen N_gen = N_reco / filter_efficiency ''' # get number of generated events f = ROOT.TFile.Open('root://t3dcachedb.psi.ch:1094/'+self.signal_file.filename, 'READ') n_reco = PlottingTools.getNminiAODEvts(self, f) n_gen = n_reco / self.signal_file.filter_efficiency # get number of selected reco events quantity = Quantity(name_flat='hnl_mass', nbins=1, bin_min=0, bin_max=1000) hist_flat_bin = PlottingTools.createHisto(self, f, 'signal_tree', quantity, branchname='flat', selection='ismatched==1' if self.selection=='' else 'ismatched==1 && '+self.selection) n_selected_bin = hist_flat_bin.GetBinContent(1) #print 'n_selected_bin',n_selected_bin efficiency = n_selected_bin / n_gen #print 'efficiency',efficiency return efficiency
def generate(): magnitudes = list(map(int, MagnitudeValues)) derivatives = list(map(int, DerivativeValues)) system = { "Bathtub": { "Volume": (magnitudes, derivatives) }, "Tab": { # ASSUMPTION: Inflow has no negative magnitude. "Inflow": (magnitudes[1:], derivatives) }, "Drain": { "Outflow": (magnitudes, derivatives) } } states = [] temp = [] for s in system: for quantity in system[s]: print(system[s]) temp.extend(system[s][quantity]) prod = product(*temp) for p in prod: idx = 0 state = {} for s in system: state[s] = {} for quantity in system[s]: mag_bound = system[s][quantity][0][-1] q = Quantity(Magnitude(p[idx], maximum=mag_bound), Derivative(p[idx + 1])) state[s][quantity] = q idx += 2 states.append(state) return states
def reserve_quantity_for_tick(self, order_id, quantity): """ :param order_id: The order id from another peer that the quantity needs to be reserved for :param quantity: The quantity to reserve :type order_id: OrderId :type quantity: Quantity :return: True if the quantity was reserved, False otherwise :rtype: bool """ assert isinstance(order_id, OrderId), type(order_id) assert isinstance(quantity, Quantity), type(quantity) if self.available_quantity >= quantity: if order_id not in self._reserved_ticks: self._logger.debug("Reserving quantity %s for order %s (own order id: %s), total quantity: %s, traded: %s", quantity, str(order_id), str(self.order_id), self.total_quantity, self.traded_quantity) self._reserved_quantity += quantity self._reserved_ticks[order_id] = quantity assert self.available_quantity >= Quantity(0) return True else: return False