예제 #1
0
    def send_to_algo(
            self, contract_order_to_trade: contractOrder
    ) -> (Algo, orderWithControls):

        log = contract_order_to_trade.log_with_attributes(self.log)
        instrument_order = self.get_parent_of_contract_order(
            contract_order_to_trade)

        contract_order_to_trade_with_algo_set = check_and_if_required_allocate_algo_to_single_contract_order(
            data=self.data,
            contract_order=contract_order_to_trade,
            instrument_order=instrument_order)

        log.msg("Sending order %s to algo %s" %
                (str(contract_order_to_trade_with_algo_set),
                 contract_order_to_trade_with_algo_set.algo_to_use))

        algo_class_to_call = self.add_controlling_algo_to_order(
            contract_order_to_trade_with_algo_set)
        algo_instance = algo_class_to_call(
            self.data, contract_order_to_trade_with_algo_set)

        # THIS LINE ACTUALLY SENDS THE ORDER TO THE ALGO
        placed_broker_order_with_controls = algo_instance.submit_trade()

        if placed_broker_order_with_controls is missing_order:
            # important we do this or order will never execute
            #  if no issue here will be released once order filled
            self.contract_stack.release_order_from_algo_control(
                contract_order_to_trade_with_algo_set.order_id)
            return missing_order

        return algo_instance, placed_broker_order_with_controls
예제 #2
0
    def create_broker_order_for_contract_order(self,
                                               contract_order_id,
                                               check_if_open=True):

        original_contract_order = self.contract_stack.get_order_with_id_from_stack(
            contract_order_id)
        contract_order = self.preprocess_contract_order(
            original_contract_order, check_if_open=check_if_open)
        if contract_order is missing_order:
            return None

        contract_order = check_and_if_required_allocate_algo_to_single_contract_order(
            self.data, contract_order)
        algo_class_to_call = self.resolve_algo(contract_order)
        algo_instance = algo_class_to_call(self.data, contract_order)

        ## THIS LINE ACTUALLY SENDS THE ORDER TO THE ALGO
        broker_order_with_controls = algo_instance.submit_trade()

        if broker_order_with_controls is missing_order:
            self.contract_stack.release_order_from_algo_control(
                contract_order_id)
            return None

        broker_order_with_controls = self.add_trade_to_database(
            broker_order_with_controls)
        broker_order_with_controls = algo_instance.manage_trade(
            broker_order_with_controls)

        result = self.post_trade_processing(broker_order_with_controls)

        return result
    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
예제 #4
0
    def create_broker_order_for_contract_order(self, contract_order_id):

        original_contract_order = self.contract_stack.get_order_with_id_from_stack(contract_order_id)
        log = original_contract_order.log_with_attributes(self.log)

        ## Check the order doesn't breach trade limits
        contract_order = self.what_contract_trade_is_possible(original_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

        ## update trade limits
        self.add_trade_to_trade_limits(broker_order)

        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(broker_order_id)))
            return failure

        # ....create new algo lock
        # This means nobody else can try and execute this order until it is released
        # Only the algo itself can release!

        self.contract_stack.add_controlling_algo_ref(contract_order_id, reference_of_controlling_algo)

        # This broker order is a child of the parent contract order
        # We add 'another' child since it's valid to have multiple broker orders
        self.contract_stack.add_another_child_to_order(contract_order_id, broker_order_id)

        return success
예제 #5
0
    def create_broker_order_for_contract_order(self,
                                               contract_order_id,
                                               check_if_open=True):

        original_contract_order = self.contract_stack.get_order_with_id_from_stack(
            contract_order_id)
        if original_contract_order is missing_order:
            # weird race condition
            return failure

        contract_order = self.preprocess_contract_order(
            original_contract_order, check_if_open=check_if_open)
        if contract_order is missing_order:
            #print("Empty order not submitting to algo")
            return None

        contract_order = check_and_if_required_allocate_algo_to_single_contract_order(
            self.data, contract_order)

        log = contract_order.log_with_attributes(self.log)
        log.msg("Sending order %s to algo %s" %
                (str(contract_order), contract_order.algo_to_use))

        algo_class_to_call = self.resolve_algo(contract_order)
        algo_instance = algo_class_to_call(self.data, contract_order)

        # THIS LINE ACTUALLY SENDS THE ORDER TO THE ALGO
        broker_order_with_controls = algo_instance.submit_trade()

        if broker_order_with_controls is missing_order:
            self.contract_stack.release_order_from_algo_control(
                contract_order_id)
            return None

        broker_order_with_controls = self.add_trade_to_database(
            broker_order_with_controls)
        broker_order_with_controls = algo_instance.manage_trade(
            broker_order_with_controls)

        result = self.post_trade_processing(broker_order_with_controls)

        return result
    def create_broker_order_for_contract_order(self, contract_order_id, check_if_open=True):

        original_contract_order = self.contract_stack.get_order_with_id_from_stack(contract_order_id)
        log = original_contract_order.log_with_attributes(self.log)

        data_locks = dataLocks(self.data)

        instrument_locked = data_locks.is_instrument_locked(original_contract_order.instrument_code)
        if instrument_locked:
            log.msg("Instrument is locked, not spawning order")
            return None

        if check_if_open:
            data_broker = dataBroker(self.data)
            market_open = data_broker.is_instrument_code_and_contract_date_okay_to_trade(original_contract_order.instrument_code,
                                                                              original_contract_order.contract_id)
            if not market_open:
                return None

        # We can deal with partially filled contract orders: that's how hard we are!
        remaining_contract_order = original_contract_order.order_with_remaining()

        ## Check the order doesn't breach trade limits
        contract_order = self.what_contract_trade_is_possible(remaining_contract_order)

        ## Note we don't save the algo method, but reallocate each time
        ## This is useful if trading is about to finish, because we switch to market orders
        ##   (assuming a bunch of limit orders haven't worked out so well)

        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

        ## update trade limits
        self.add_trade_to_trade_limits(broker_order)

        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(broker_order_id)))
            return failure

        # ....create new algo lock
        # This means nobody else can try and execute this order until it is released
        # Only the algo itself can release!
        # This only applies to 'fire and forget' orders that aren't controlled by an algo

        self.contract_stack.add_controlling_algo_ref(contract_order_id, reference_of_controlling_algo)

        # This broker order is a child of the parent contract order
        # We add 'another' child since it's valid to have multiple broker orders
        self.contract_stack.add_another_child_to_order(contract_order_id, broker_order_id)

        return success