def clear_parents_and_children_if_all_modification_rejected(self, instrument_order_id): parent_order = self.instrument_stack.get_order_with_id_from_stack(instrument_order_id) log = log_attributes_from_instrument_order(self.log, parent_order) list_of_child_order_ids = parent_order.children list_of_child_orders = [self.contract_stack.get_order_with_id_from_stack(child_order_id) \ for child_order_id in list_of_child_order_ids] # Check all child orders are in 'rejected' state # If any aren't we can't do this # This shouldn't happen since we only mark parent orders as rejected once all the kids are for child_order in list_of_child_orders: if not child_order.is_order_modification_rejected(): child_log = log_attributes_from_contract_order(self.log, child_order) child_log.warn("Instrument order %s has rejected modifying but child contract order %s has not! Can't clear modifications" % \ (str(parent_order), str(child_order))) return failure for child_order_id in list_of_child_order_ids: result = self.contract_stack.clear_modification_of_order_on_stack(child_order_id) if result is failure: log.warn("Can't clear modifications for contract order %d child of %s" % (child_order_id, str(parent_order))) return failure # Children are completed, we can do parent result = self.instrument_stack.clear_modification_of_order_on_stack(instrument_order_id) if result is failure: log = log_attributes_from_instrument_order(self.log, parent_order) log.warn("Cleared modifications for contract order children, but can't clear parent instrument order %s!" % parent_order) return failure return success
def pass_modification_from_parent_to_children(self, instrument_order_id): """ Modifications will depend on the parent/child relationship: :param instrument_order_id: :return: """ instrument_order = self.instrument_stack.get_order_with_id_from_stack(instrument_order_id) child_order_ids = instrument_order.children log = log_attributes_from_instrument_order(self.log, instrument_order) if child_order_ids is no_children: # No children result = self._modify_childless_instrument_order(instrument_order_id) return result elif len(child_order_ids)==1: # Dead simple: one child child_id = child_order_ids[0] result = self._modify_single_child_order(child_id, instrument_order) return result else: # multiple children result = self._modify_multiple_child_orders(instrument_order) return result
def spawn_children_from_instrument_order_id(self, instrument_order_id): instrument_order = self.instrument_stack.get_order_with_id_from_stack(instrument_order_id) if instrument_order is missing_order: return failure log = log_attributes_from_instrument_order(self.log, instrument_order) list_of_contract_orders = spawn_children_from_instrument_order(self.data, instrument_order) log.msg("List of contract orders spawned %s" % str(list_of_contract_orders)) list_of_child_ids = self.contract_stack.put_list_of_orders_on_stack(list_of_contract_orders) if list_of_child_ids is failure: log.msg("Failed to create child orders %s from parent order %s" % (str(list_of_contract_orders), str(instrument_order))) return failure for contract_order, child_id in zip(list_of_contract_orders, list_of_child_ids): child_log = log_attributes_from_contract_order(log, contract_order) child_log.msg("Put child order %s on contract_stack with ID %d from parent order %s" % (str(contract_order), child_id, str(instrument_order))) result = self.instrument_stack.add_children_to_order(instrument_order.order_id, list_of_child_ids) if result is not success: log.msg("Error %s when adding children to instrument order %s" % (str(result), str(instrument_order))) return failure return success
def clear_parents_and_children_if_all_modification_complete( self, instrument_order_id): parent_order = self.instrument_stack.get_order_with_id_from_stack( instrument_order_id) log = log_attributes_from_instrument_order(self.log, parent_order) list_of_child_order_ids = parent_order.children list_of_child_orders = [self.contract_stack.get_order_with_id_from_stack(child_order_id) \ for child_order_id in list_of_child_order_ids] # Check all child orders are in 'completed modifying' state # if any are not, we can't do this # (this shouldn't happen, since we only set parent order to completed modifying when all children are set) for child_order in list_of_child_orders: child_log = log_attributes_from_contract_order( self.log, child_order) if not child_order.is_order_finished_modifying(): child_log.warn("Instrument order %s has finished modifying but child contract order %s has not! Can't clear modifications" % \ (str(parent_order), str(child_order))) return failure # clear the modifications for the children for child_order_id in list_of_child_order_ids: result = self.contract_stack.clear_modification_of_order_on_stack( child_order_id) if result is failure: log.warn( "Can't clear modifications for contract order %d, child of parent %s" % (child_order_id, str(parent_order))) return failure # Children are completed, we can do parent result = self.instrument_stack.clear_modification_of_order_on_stack( instrument_order_id) if result is failure: instrument_log = log_attributes_from_instrument_order( self.log, parent_order) instrument_log.warn( "Cleared modifications for contract order children, but can't clear parent instrument order %s!" % parent_order) return failure return success
def _modify_childless_instrument_order(self, instrument_order_id): instrument_order = self.instrument_stack.get_order_with_id_from_stack(instrument_order_id) log = log_attributes_from_instrument_order(self.log, instrument_order) # We can mark the parent order as completed modifying and clear the modification log.msg("Instrument order %s has no children so modification can take place" % str(instrument_order)) result = self.instrument_stack.completed_modifying_order_on_stack(instrument_order_id) if result is failure: return failure result = self.instrument_stack.clear_modification_of_order_on_stack(instrument_order_id) return result
def _modify_multiple_child_orders(self, instrument_order): """ OK, it's got multiple child orders. This is more complicated... We now have a series of possibilites: - equal and opposite positions in each (eg roll order on outright legs, spread instrument) - opposite but not equal positions in each (spread instrument) - same sign positions in each (passive roll order) It's far too complicated to try and deal with all these cases. So instead we allow a cancellation order to go ahead (where there is zero unfilled quantity left), but all other types of modifications are rejected """ log = log_attributes_from_instrument_order(self.log, instrument_order) parent_order_can_be_cancelled = instrument_order.fill_equals_modification_quantity( ) if not parent_order_can_be_cancelled: log.warn( "Instrument order %s has multiple children and isn't a full cancellation: can't be modified" % str(instrument_order)) return failure child_order_ids = instrument_order.children for child_id in child_order_ids: child_order = self.contract_stack.get_order_with_id_from_stack( child_id) if child_order is missing_order: log.warn( "Child order orderid % is missing for instrument order %s, can't pass on modification" % (child_id, str(instrument_order))) return failure child_log = log_attributes_from_contract_order( self.log, child_order) result = self.contract_stack.cancel_order(child_id) if type(result) is int: # successful cancellation modification continue elif result is order_is_in_status_modified: # Modification is already happening, probably from a previous run of this code continue else: child_log.warn( "Couldn't pass modification from parent instrument order %s to child %s error %s" % (str(instrument_order), str(child_order), str(result))) continue return success