コード例 #1
0
ファイル: broker.py プロジェクト: t-triobox/pysystemtrade
    def get_and_submit_broker_order_for_contract_order_as_market_order_with_quantity(
            self, contract_order, qty):

        log = log_attributes_from_contract_order(self.data.log, contract_order)
        broker = self.get_broker_name()
        broker_account = self.get_broker_account()
        broker_clientid = self.get_broker_clientid()

        # Check market closed?
        side_price, mid_price = self.check_market_conditions_for_contract_order(
            contract_order)

        broker_order = create_new_broker_order_from_contract_order(
            contract_order,
            qty,
            order_type="market",
            side_price=side_price,
            mid_price=mid_price,
            algo_comment="market order",
            broker=broker,
            broker_account=broker_account,
            broker_clientid=broker_clientid)

        submitted_broker_order = self.\
            submit_broker_order(broker_order)

        if submitted_broker_order is missing_order:
            return missing_order

        return submitted_broker_order
コード例 #2
0
    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
コード例 #3
0
    def pass_modification_complete_from_child_to_parent_orders(self, contract_order_id):
        # ... if and only if *all* children are in modification complete state

        child_order = self.contract_stack.get_order_with_id_from_stack(contract_order_id)
        log = log_attributes_from_contract_order(self.log, child_order)
        parent_order_id = child_order.parent
        if parent_order_id is no_parent:
            log.warn("No parent order for child order %s when trying to mark modification as complete" %
                          (str(child_order)))

            return failure

        instrument_order = self.instrument_stack.get_order_with_id_from_stack(parent_order_id)
        # Check that all children have completed modifying
        child_id_list = instrument_order.children
        if child_id_list is no_children:
            log.warn("Reckless parenting! Instrument order %s has no children but child order %s thinks it is the parent when trying to mark modification as complete" %
                     (str(instrument_order), str(child_order)))

            return failure

        flag_completed = [self.contract_stack.is_finished_modified(other_child_order_id) for
                          other_child_order_id in child_id_list]
        if not all(flag_completed):
            # Can't mark parent order as complete until all children are complete
            return failure

        result = self.instrument_stack.completed_modifying_order_on_stack(parent_order_id)
        if result is failure:
            log.warn("Couldn't pass modification from child order %s up to parent order %d" %
                          (str(child_order), parent_order_id))

            return failure

        return success
コード例 #4
0
    def pass_modification_rejection_from_child_to_parent_order(self, contract_order_id):
        # if any child order is rejected, then we also reject the parent and all other child orders
        child_order = self.contract_stack.get_order_with_id_from_stack(contract_order_id)
        log = log_attributes_from_contract_order(self.log, child_order)
        parent_order_id = child_order.parent
        if parent_order_id is no_parent:
            log.warn("No parent order for child order %s when trying to mark modification as rejected" %
                          (str(child_order)))

            return failure

        instrument_order = self.instrument_stack.get_order_with_id_from_stack(parent_order_id)

        # All children should also be rejected
        child_id_list = instrument_order.children
        if child_id_list is no_children:
            log.warn("Reckless parenting! Instrument order %s has no children but child order %s thinks it is the parent when trying to mark modification as complete" %
                     (str(instrument_order), str(child_order)))

            return failure

        for other_child_id in child_id_list:
            result = self.contract_stack.reject_order_on_stack(other_child_id)
            if result is not success:
                log.warn("Couldn't mark child order %d as rejected when another child %s was rejected" % (other_child_id, str(child_order)))
                return failure

        result = self.instrument_stack.reject_order_on_stack(parent_order_id)
        if result is not success:
            log.warn("Couldn't pass reject modification from child order %s up to parent order %d" %
                          (str(child_order), parent_order_id))

            return failure

        return success
コード例 #5
0
    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 create_broker_order_for_contract_order(self, contract_order_id):

        ## This next line prevents another process or algo having a go
        TEMPORARY_ALGO_REFERENCE = 'Locked-for-writing'
        self.contract_stack.add_controlling_algo_ref(contract_order_id,
                                                     TEMPORARY_ALGO_REFERENCE)

        contract_order = self.contract_stack.get_order_with_id_from_stack(
            contract_order_id)
        log = log_attributes_from_contract_order(self.log, contract_order)

        contract_order = check_and_if_required_allocate_algo_to_single_contract_order(
            self.data, contract_order)

        algo_to_use_str = contract_order.algo_to_use
        algo_method = resolve_function(algo_to_use_str)

        ## The algo method submits an order to the broker, and returns a broker order object
        ## We then save the brokerorder in the broker stack, and add it as a child to a contract order
        ## Algos may be 'fire and forget' (a simple market order, as implemented initially) or 'active'
        ## Active algos need to keep running on another thread (need to work out how to do this)
        ## They will set the property 'reference_of_controlling_algo' in contract order
        ## Fills are picked up by another process (or if the algo is an active thing, potentially by itself)

        broker_order, reference_of_controlling_algo = algo_method(
            self.data, contract_order)
        if broker_order is missing_order:
            # something bad has happened and we can't submit an order to the broker
            # Nae bother, maybe try again later
            # Unlock the contract order in case we want to do this later
            self.contract_stack.release_order_from_algo_control(
                contract_order_id)
            return None

        broker_order_id = self.broker_stack.put_order_on_stack(broker_order)
        if type(broker_order_id) is not int:
            # We've created a broker order but can't add it to the broker order database
            # Probably safest to leave the contract order locked otherwise there could be multiple
            #   broker orders issued and nobody wants that!
            log.critical(
                "Created a broker order %s but can't add it to the order stack!! (condition %s)"
                % (str(broker_order), str(e)))
            return failure

        ## Release the temporary algo lock
        self.contract_stack.release_order_from_algo_control(contract_order_id)

        # Create new algo lock
        # This means nobody else can try and execute this order until it is released

        self.contract_stack.add_controlling_algo_ref(
            contract_order_id, reference_of_controlling_algo)

        self.contract_stack.add_another_child_to_order(contract_order_id,
                                                       broker_order_id)

        return success
コード例 #7
0
    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
コード例 #8
0
    def _modify_single_child_order_where_child_is_single_contract(self, child_id, instrument_order):
        child_order = self.contract_stack.get_order_with_id_from_stack(child_id)
        child_log = log_attributes_from_contract_order(self.log, child_order)
        modification_quantity = instrument_order.modification_quantity

        result = self.contract_stack.modify_order_on_stack(child_id, [modification_quantity])

        if result is success:
            # fine
            return success
        elif result is order_is_in_status_modified:
            # Modification is already happening, probably from a previous run of this code
            return success
        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)))
            return failure
コード例 #9
0
    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
コード例 #10
0
def algo_market(data, contract_order):
    """
    Simplest possible execution algo
    Submits a single market order for the entire quantity

    :param data: dataBlob
    :param contract_order: contractOrder

    :returns: tuple, (broker_order, reference of controlling algo)
    """
    log = log_attributes_from_contract_order(data.log, contract_order)

    if not contract_order.fill_equals_zero():
        log.warn("Simple market algo can only deal with orders that have no existing fill, not %s!" % str(contract_order))
        return missing_order, ""

    qty = contract_order.trade

    if len(qty)>1:
        log.warn("Simple market algo can't yet deal with spread order' %s!" % str(
            contract_order))
        return missing_order, ""

    ## do full order
    qty_for_broker = qty

    data_broker = dataBroker(data)

    broker_order = data_broker.get_and_submit_broker_order_for_contract_order_as_market_order_with_quantity(contract_order, qty_for_broker)

    ## Need some kind of keystore for controlling Algos
    ## However as this is a 'fire and forget' algo that just runs once without any permanent thread
    ##   this doesn't matter, except perhaps for some complex case that we don't want to worry about right now
    ## When we introduce hooks for picking up fills, we're probably going to want to do this properly

    reference_of_controlling_algo = "algo_market"

    return broker_order, reference_of_controlling_algo
コード例 #11
0
    def generate_force_roll_orders_for_instrument(self, instrument_code):
        log = self.data.log.setup(instrument_code=instrument_code,
                                  strategy_name=ROLL_PSEUDO_STRATEGY)

        instrument_order, contract_orders = create_force_roll_orders(
            self.data, instrument_code)
        # Create a pseudo instrument order and a set of contract orders
        # This will also prevent trying to generate more than one set of roll orders

        if len(contract_orders) == 0 or instrument_order is missing_order:
            # No orders
            return None

        # Do as a transaction: if everything doesn't go to plan can roll back
        instrument_order.lock_order()
        instrument_order_id = self.instrument_stack.put_order_on_stack(
            instrument_order, allow_zero_orders=True)

        if type(instrument_order_id) is not int:
            if instrument_order_id is duplicate_order:
                # Probably already done this
                return success
            else:
                log.msg(
                    "Couldn't put roll order %s on instrument order stack error %s"
                    % (str(instrument_order), str(instrument_order_id)))
            return failure

        for child_order in contract_orders:
            child_order.parent = instrument_order_id

        # Do as a transaction: if everything doesn't go to plan can roll back
        # if this try fails we will roll back the instrument commit
        try:
            log = log.setup(instrument_order_id=instrument_order_id)

            log.msg("List of roll contract orders spawned %s" %
                    str(contract_orders))
            list_of_child_order_ids = self.contract_stack.put_list_of_orders_on_stack(
                contract_orders, unlock_when_finished=False)

            if list_of_child_order_ids is failure:
                log.msg("Failed to add roll contract orders to stack %s" %
                        (str(contract_orders)))
                list_of_child_order_ids = []
                raise Exception

            for roll_order, order_id in zip(contract_orders,
                                            list_of_child_order_ids):
                child_log = log_attributes_from_contract_order(log, roll_order)
                child_log.msg(
                    "Put roll order %s on contract_stack with ID %d from parent order %s"
                    % (str(roll_order), order_id, str(instrument_order)))

            self.instrument_stack._unlock_order_on_stack(instrument_order_id)
            result = self.instrument_stack.add_children_to_order(
                instrument_order_id, list_of_child_order_ids)
            if result is not success:
                log.msg(
                    "Error %s when adding children to instrument roll order %s"
                    % (str(result), str(instrument_order)))
                raise Exception

        except:
            ## Roll back instrument order
            self.instrument_stack._unlock_order_on_stack(instrument_order_id)
            self.instrument_stack.deactivate_order(instrument_order_id)
            self.instrument_stack.remove_order_with_id_from_stack(
                instrument_order_id)

            # If any children, roll them back also
            if len(list_of_child_order_ids) > 0:
                self.contract_stack.rollback_list_of_orders_on_stack(
                    list_of_child_order_ids)

            return failure

        return success