예제 #1
0
    def _get_ib_futures_contract(self, futures_contract_object):
        """
        Return a complete and unique IB contract that matches futures_contract_object
        This is expensive so not called directly, only by ib_futures_contract which does caching

        :param futures_contract_object: contract, containing instrument metadata suitable for IB
        :return: a single ib contract object
        """
        # Convert to IB world
        instrument_object_with_metadata = futures_contract_object.instrument
        ibcontract = ib_futures_instrument(instrument_object_with_metadata)

        # Register the contract to make logging and error handling cleaner
        self.add_contract_to_register(
            ibcontract,
            log_tags=dict(instrument_code=instrument_object_with_metadata.
                          instrument_code,
                          contract_date=futures_contract_object.date))

        # The contract date might be 'yyyymm' or 'yyyymmdd'
        contract_day_passed = futures_contract_object.contract_date.is_day_defined(
        )
        if contract_day_passed:
            ## Already have the expiry
            contract_date = futures_contract_object.contract_date
        else:
            ## Don't have the expiry so lose the days at the end so it's just 'YYYYMM'
            contract_date = str(futures_contract_object.contract_date)[:6]

        ibcontract.lastTradeDateOrContractMonth = contract_date

        ## We allow multiple contracts in case we have 'yyyymm' and not specified expiry date for VIX
        ibcontract_list = self.ib_get_contract_chain(ibcontract)

        if len(ibcontract_list) == 0:
            ## No contracts found
            return missing_contract

        if len(ibcontract_list) == 1:
            ## OK no hassle, only one contract no confusion
            resolved_contract = ibcontract_list[0]
        else:
            ## It might be a contract with weekly expiries (probably VIX)
            ## We need to find the right one
            try:
                resolved_contract = resolve_multiple_expiries(
                    ibcontract_list, instrument_object_with_metadata)
            except Exception as exception:
                self.log.warn(
                    "%s could not resolve contracts: %s" %
                    (str(instrument_object_with_metadata), exception.args[0]))

                return missing_contract

        return resolved_contract
예제 #2
0
    def _get_vanilla_ib_futures_contract(
            self, futures_instrument_with_ib_data: futuresInstrumentWithIBData,
            contract_date):
        """
        Return a complete and unique IB contract that matches contract_object_with_ib_data
        This is expensive so not called directly, only by ib_futures_contract which does caching

        :param contract_object_with_ib_data: contract, containing instrument metadata suitable for IB
        :return: a single ib contract object
        """

        # The contract date might be 'yyyymm' or 'yyyymmdd'
        ibcontract = ib_futures_instrument(futures_instrument_with_ib_data)

        contract_day_passed = contract_date.is_day_defined()
        if contract_day_passed:
            # Already have the expiry
            pass
        else:
            # Don't have the expiry so lose the days at the end so it's just
            # 'YYYYMM'
            contract_date = str(contract_date)[:6]

        ibcontract.lastTradeDateOrContractMonth = contract_date

        # We allow multiple contracts in case we have 'yyyymm' and not
        # specified expiry date for VIX
        ibcontract_list = self.ib_get_contract_chain(ibcontract)

        if len(ibcontract_list) == 0:
            # No contracts found
            return missing_contract

        if len(ibcontract_list) == 1:
            # OK no hassle, only one contract no confusion
            resolved_contract = ibcontract_list[0]
        else:
            # It might be a contract with weekly expiries (probably VIX)
            # We need to find the right one
            try:
                resolved_contract = resolve_multiple_expiries(
                    ibcontract_list, futures_instrument_with_ib_data)
            except Exception as exception:
                self.log.warn(
                    "%s could not resolve contracts: %s" %
                    (str(futures_instrument_with_ib_data), exception.args[0]))

                return missing_contract

        return resolved_contract
예제 #3
0
    def _get_spread_ib_futures_contract(
        self,
        futures_instrument_with_ib_data: futuresInstrumentWithIBData,
        contract_date,
        trade_list_for_multiple_legs=[-1, 1],
    ):
        """
        Return a complete and unique IB contract that matches contract_object_with_ib_data
        This is expensive so not called directly, only by ib_futures_contract which does caching

        :param contract_object_with_ib_data: contract, containing instrument metadata suitable for IB
        :return: a single ib contract object
        """
        # Convert to IB world
        ibcontract = ib_futures_instrument(futures_instrument_with_ib_data)
        ibcontract.secType = "BAG"

        list_of_contract_dates = contract_date.list_of_single_contract_dates
        resolved_legs = [
            self._get_vanilla_ib_futures_contract(
                futures_instrument_with_ib_data, contract_date)
            for contract_date in list_of_contract_dates
        ]

        ratio_list = list_of_ints_with_highest_common_factor_positive_first(
            trade_list_for_multiple_legs)

        def _get_ib_combo_leg(ratio, resolved_leg):

            leg = ComboLeg()
            leg.conId = int(resolved_leg.conId)
            leg.exchange = str(resolved_leg.exchange)

            action, size = resolveBS(ratio)

            leg.ratio = int(size)
            leg.action = str(action)

            return leg

        ibcontract.comboLegs = [
            _get_ib_combo_leg(ratio, resolved_leg)
            for ratio, resolved_leg in zip(ratio_list, resolved_legs)
        ]

        return ibcontract, resolved_legs
예제 #4
0
    def broker_get_futures_contract_list(self,
                                         instrument_object_with_ib_config):

        specific_log = self.log.setup(
            instrument_code=instrument_object_with_ib_config.instrument_code)

        ibcontract_pattern = ib_futures_instrument(
            instrument_object_with_ib_config)
        contract_list = self.ib_get_contract_chain(ibcontract_pattern,
                                                   log=specific_log)
        # if no contracts found will be empty

        # Extract expiry date strings from these
        contract_dates = [
            ibcontract.lastTradeDateOrContractMonth
            for ibcontract in contract_list
        ]

        return contract_dates