def cancel_market_data_for_contract_object(
        self, contract_object: futuresContract, trade_list_for_multiple_legs=None
    ):
        """
        Returns my encapsulation of a ticker object

        :param contract_object:
        :param trade_list_for_multiple_legs:
        :return:
        """

        new_log = contract_object.log(self.log)

        contract_object_with_ib_data = (
            self.futures_contract_data.get_contract_object_with_IB_data(
                contract_object
            )
        )
        if contract_object_with_ib_data is missing_contract:
            new_log.warn("Can't get data for %s" % str(contract_object))
            return futuresContractPrices.create_empty()

        self.ibconnection.cancel_market_data_for_contract_object(
            contract_object_with_ib_data,
            trade_list_for_multiple_legs=trade_list_for_multiple_legs,
        )
Exemple #2
0
    def write_prices_for_contract_object(
            self,
            futures_contract_object: futuresContract,
            futures_price_data: futuresContractPrices,
            ignore_duplication=False):
        """
        Write some prices

        :param futures_contract_object:
        :param futures_price_data:
        :param ignore_duplication: bool, to stop us overwriting existing prices
        :return: None
        """

        if self.has_data_for_contract(futures_contract_object):
            if ignore_duplication:
                pass
            else:
                log = futures_contract_object.log(self.log)
                log.warn("There is already existing data for %s" %
                         futures_contract_object.key)
                return None

        self._write_prices_for_contract_object_no_checking(
            futures_contract_object, futures_price_data)
Exemple #3
0
    def _get_prices_at_frequency_for_contract_object_no_checking(
        self,
        contract_object: futuresContract,
        freq: Frequency,
        allow_expired=False,
    ) -> futuresContractPrices:
        """
        Get historical prices at a particular frequency

        We override this method, rather than _get_prices_at_frequency_for_contract_object_no_checking
        Because the list of dates returned by contracts_with_price_data is likely to not match (expiries)

        :param contract_object:  futuresContract
        :param freq: str; one of D, H, 15M, 5M, M, 10S, S
        :return: data
        """
        new_log = contract_object.log(self.log)

        contract_object_with_ib_broker_config = (
            self.futures_contract_data.get_contract_object_with_IB_data(
                contract_object, allow_expired=allow_expired))
        if contract_object_with_ib_broker_config is missing_contract:
            new_log.warn("Can't get data for %s" % str(contract_object))
            return futuresContractPrices.create_empty()

        price_data = self._get_prices_at_frequency_for_ibcontract_object_no_checking(
            contract_object_with_ib_broker_config,
            freq=freq,
            allow_expired=allow_expired,
        )

        return price_data
Exemple #4
0
    def get_recent_bid_ask_tick_data_for_contract_object(
            self, contract_object: futuresContract) -> dataFrameOfRecentTicks:
        """
        Get last few price ticks

        :param contract_object: futuresContract
        :return:
        """
        new_log = contract_object.log(self.log)

        contract_object_with_ib_data = (
            self.futures_contract_data.get_contract_object_with_IB_data(
                contract_object))
        if contract_object_with_ib_data is missing_contract:
            new_log.warn("Can't get data for %s" % str(contract_object))
            return dataFrameOfRecentTicks.create_empty()

        tick_data = self.ib_client.ib_get_recent_bid_ask_tick_data(
            contract_object_with_ib_data)

        if tick_data is missing_contract:
            return missing_data

        tick_data_as_df = from_ib_bid_ask_tick_data_to_dataframe(tick_data)

        return tick_data_as_df
Exemple #5
0
    def is_contract_okay_to_trade(self, futures_contract: futuresContract) -> bool:
        new_log = futures_contract.log(self.log)
        trading_hours = self.get_trading_hours_for_contract(futures_contract)
        if trading_hours is missing_contract:
            new_log.critical(
                "Error! Cannot find active contract! Expired? interactive_update_roll_status.py not executed?"
            )
            return False

        return trading_hours.okay_to_trade_now()
Exemple #6
0
    def update_prices_for_contract(
            self,
            contract_object: futuresContract,
            new_futures_per_contract_prices: futuresContractPrices,
            check_for_spike: bool = True,
            max_price_spike: float = VERY_BIG_NUMBER) -> int:
        """
        Reads existing data, merges with new_futures_prices, writes merged data

        :param new_futures_prices:
        :return: int, number of rows
        """
        new_log = contract_object.log(self.log)

        if len(new_futures_per_contract_prices) == 0:
            new_log.msg("No new data")
            return 0

        old_prices = self.get_prices_for_contract_object(contract_object)
        merged_prices = old_prices.add_rows_to_existing_data(
            new_futures_per_contract_prices,
            check_for_spike=check_for_spike,
            max_price_spike=max_price_spike)

        if merged_prices is spike_in_data:
            new_log.msg(
                "Price has moved too much - will need to manually check - no price update done"
            )
            return spike_in_data

        rows_added = len(merged_prices) - len(old_prices)

        if rows_added < 0:
            new_log.critical("Can't remove prices something gone wrong!")
            return failure

        elif rows_added == 0:
            if len(old_prices) == 0:
                new_log.msg("No existing or additional data")
                return 0
            else:
                new_log.msg("No additional data since %s " %
                            str(old_prices.index[-1]))
            return 0

        # We have guaranteed no duplication
        self.write_prices_for_contract_object(contract_object,
                                              merged_prices,
                                              ignore_duplication=True)

        new_log.msg("Added %d additional rows of data" % rows_added)

        return rows_added
    def _get_actual_expiry_date_given_contract_with_ib_metadata(
            self, contract_object_with_ib_data: futuresContract) -> expiryDate:
        expiry_date = self.ibconnection.broker_get_contract_expiry_date(
            contract_object_with_ib_data)

        if expiry_date is missing_contract:
            log = contract_object_with_ib_data.log(self.log)
            log.msg("No IB expiry date found")
            return missing_contract
        else:
            expiry_date = expiryDate.from_str(expiry_date)

        return expiry_date
Exemple #8
0
    def _get_prices_at_frequency_for_contract_object_no_checking(self, contract_object: futuresContract,
                                                                 freq: str
                                                    ) -> futuresContractPrices:

        """
        Get historical prices at a particular frequency

        We override this method, rather than _get_prices_at_frequency_for_contract_object_no_checking
        Because the list of dates returned by contracts_with_price_data is likely to not match (expiries)

        :param contract_object:  futuresContract
        :param freq: str; one of D, H, 15M, 5M, M, 10S, S
        :return: data
        """
        new_log = contract_object.log(self.log)

        contract_object_with_ib_broker_config = (
            self.futures_contract_data.get_contract_object_with_IB_data(
                contract_object
            )
        )
        if contract_object_with_ib_broker_config is missing_contract:
            new_log.warn("Can't get data for %s" % str(contract_object))
            return futuresContractPrices.create_empty()

        price_data = self.ib_client.broker_get_historical_futures_data_for_contract(
            contract_object_with_ib_broker_config, bar_freq=freq)

        if price_data is missing_data:
            new_log.warn(
                "Something went wrong getting IB price data for %s" %
                str(contract_object))
            price_data = futuresContractPrices.create_empty()

        elif len(price_data) == 0:
            new_log.warn(
                "No IB price data found for %s" %
                str(contract_object))
            price_data = futuresContractPrices.create_empty()
        else:
            price_data = futuresContractPrices(price_data)

        ## It's important that the data is in local time zone so that this works
        price_data = price_data.remove_future_data()

        ## Some contract data is marked to model, don't want this
        price_data = price_data.remove_zero_volumes()

        return price_data
Exemple #9
0
    def _delete_prices_for_contract_object_with_no_checks_be_careful(
            self, futures_contract_object: futuresContract):
        """
        Delete prices for a given contract object without performing any checks

        WILL THIS WORK IF DOESN'T EXIST?
        :param futures_contract_object:
        :return: None
        """
        log = futures_contract_object.log(self.log)

        ident = from_contract_to_key(futures_contract_object)
        self.arctic_connection.delete(ident)
        log.msg("Deleted all prices for %s from %s" %
                (futures_contract_object.key, str(self)))
    def get_min_tick_size_for_contract(self, contract_object: futuresContract) -> float:
        new_log = contract_object.log(self.log)
        contract_object_with_ib_data = self.get_contract_object_with_IB_data(contract_object)
        if contract_object_with_ib_data is missing_contract:
            new_log.msg("Can't resolve contract so can't find tick size")
            return missing_contract

        min_tick_size = self.ibconnection.ib_get_min_tick_size(
            contract_object_with_ib_data
        )

        if min_tick_size is missing_contract:
            new_log.msg("No tick size found")
            return missing_contract

        return min_tick_size
    def _get_prices_for_contract_object_no_checking(
        self, futures_contract_object: futuresContract
    ) -> futuresContractPrices:
        """
        Read back the prices for a given contract object

        :param contract_object:  futuresContract
        :return: data
        """
        keyname = self._keyname_given_contract_object(futures_contract_object)
        filename = self._filename_given_key_name(keyname)
        config = self.config

        date_format = config.input_date_format
        date_time_column = config.input_date_index_name
        input_column_mapping = config.input_column_mapping
        skiprows = config.input_skiprows
        skipfooter = config.input_skipfooter
        multiplier = config.apply_multiplier
        inverse = config.apply_inverse

        try:
            instrpricedata = pd_readcsv(
                filename,
                date_index_name=date_time_column,
                date_format=date_format,
                input_column_mapping=input_column_mapping,
                skiprows=skiprows,
                skipfooter=skipfooter,
            )
        except OSError:
            log = futures_contract_object.log(self.log)
            log.warn("Can't find adjusted price file %s" % filename)
            return futuresContractPrices.create_empty()

        instrpricedata = instrpricedata.groupby(level=0).last()
        for col_name in ["OPEN", "HIGH", "LOW", "FINAL"]:
            column_series = instrpricedata[col_name]
            if inverse:
                column_series = 1 / column_series
            column_series *= multiplier
            instrpricedata[col_name] = column_series.round(2)

        instrpricedata = futuresContractPrices(instrpricedata)

        return instrpricedata
    def delete_prices_for_contract_object(
            self, futures_contract_object: futuresContract, areyousure=False):
        """

        :param futures_contract_object:
        :return:
        """

        if not areyousure:
            raise Exception(
                "You have to be sure to delete prices_for_contract_object!")

        if self.has_data_for_contract(futures_contract_object):
            self._delete_prices_for_contract_object_with_no_checks_be_careful(
                futures_contract_object)
        else:
            log = futures_contract_object.log(self.log)
            log.warn("Tried to delete non existent contract")
    def update_prices_for_contract(
        self,
        contract_object: futuresContract,
        new_futures_per_contract_prices: futuresContractPrices,
        check_for_spike: bool = True,
    ) -> int:
        """
        Reads existing data, merges with new_futures_prices, writes merged data

        :param new_futures_prices:
        :return: int, number of rows
        """
        new_log = contract_object.log(self.log)

        old_prices = self.get_prices_for_contract_object(contract_object)
        merged_prices = old_prices.add_rows_to_existing_data(
            new_futures_per_contract_prices, check_for_spike=check_for_spike)

        if merged_prices is data_error:
            new_log.msg(
                "Price has moved too much - will need to manually check - no price updated done"
            )
            return data_error

        rows_added = len(merged_prices) - len(old_prices)

        if rows_added == 0:
            if len(old_prices) == 0:
                new_log.msg("No existing or additional data")
                return 0
            else:
                new_log.msg("No additional data since %s " %
                            str(old_prices.index[-1]))
            return 0

        # We have guaranteed no duplication
        self.write_prices_for_contract_object(contract_object,
                                              merged_prices,
                                              ignore_duplication=True)

        new_log.msg("Added %d additional rows of data" % rows_added)

        return rows_added
Exemple #14
0
    def _get_actual_expiry_date_given_single_contract_with_ib_metadata(self, futures_contract_with_ib_data: futuresContract) -> expiryDate:
        log = futures_contract_with_ib_data.specific_log(self.log)
        if futures_contract_with_ib_data.is_spread_contract():
            log.warn("Can't find expiry for multiple leg contract here")
            return missing_contract

        expiry_date = self.ibconnection.broker_get_single_contract_expiry_date(
            futures_contract_with_ib_data
        )

        if expiry_date is missing_contract:
            log = futures_contract_with_ib_data.log(self.log)
            log.msg("No IB expiry date found")
            return missing_contract
        else:
            expiry_date = expiryDate.from_str(
                expiry_date)

        return expiry_date
Exemple #15
0
    def add_contract_data(self,
                          contract_object: futuresContract,
                          ignore_duplication: bool = False):

        instrument_code = contract_object.instrument_code
        contract_date = contract_object.date_str

        log = contract_object.log(self.log)

        if self.is_contract_in_data(instrument_code, contract_date):
            if ignore_duplication:
                pass
            else:
                log.warn(
                    "There is already %s in the data, you have to delete it first"
                    % (contract_object.key))
                return None

        self._add_contract_object_without_checking_for_existing_entry(
            contract_object)
        log.terse("Added contract %s %s" % (instrument_code, contract_date))
Exemple #16
0
    def _write_prices_for_contract_object_no_checking(
            self, futures_contract_object: futuresContract,
            futures_price_data: futuresContractPrices):
        """
        Write prices
        CHECK prices are overriden on second write

        :param futures_contract_object: futuresContract
        :param futures_price_data: futuresContractPriceData
        :return: None
        """

        log = futures_contract_object.log(self.log)
        ident = from_contract_to_key(futures_contract_object)
        futures_price_data_as_pd = pd.DataFrame(futures_price_data)

        self.arctic_connection.write(ident, futures_price_data_as_pd)

        log.msg("Wrote %s lines of prices for %s to %s" %
                (len(futures_price_data), str(
                    futures_contract_object.key), str(self)))
    def get_actual_expiry_date_for_contract(
            self, contract_object: futuresContract) -> expiryDate:
        """
        FIXME CONSIDER USE OF get_contract_object_with_IB_data INSTEAD
        Get the actual expiry date of a contract from IB

        :param contract_object: type futuresContract
        :return: YYYYMMDD or None
        """

        log = contract_object.log(self.log)
        contract_object_with_ib_data = self._get_contract_object_with_IB_metadata(
            contract_object)
        if contract_object_with_ib_data is missing_contract:
            log.msg("Can't resolve contract so can't find expiry date")
            return missing_contract

        expiry_date = self._get_actual_expiry_date_given_contract_with_ib_metadata(
            contract_object_with_ib_data)

        return expiry_date
    def get_trading_hours_for_contract(self, futures_contract: futuresContract) :
        """

        :param futures_contract:
        :return: list of paired date times
        """
        new_log = futures_contract.log(self.log)

        contract_object_with_ib_data = self.get_contract_object_with_IB_data(futures_contract)
        if contract_object_with_ib_data is missing_contract:
            new_log.msg("Can't resolve contract")
            return missing_contract

        trading_hours = self.ibconnection.ib_get_trading_hours(
            contract_object_with_ib_data
        )

        if trading_hours is missing_contract:
            new_log.msg("No IB expiry date found")
            trading_hours = []

        return trading_hours
    def _get_prices_for_contract_object_no_checking(
            self,
            futures_contract_object: futuresContract) -> futuresContractPrices:
        """
        Read back the prices for a given contract object

        :param contract_object:  futuresContract
        :return: data
        """
        keyname = self._keyname_given_contract_object(futures_contract_object)
        filename = self._filename_given_key_name(keyname)
        config = self.config

        date_format = config.input_date_format
        date_time_column = config.input_date_index_name
        input_column_mapping = config.input_column_mapping
        skiprows = config.input_skiprows
        skipfooter = config.input_skipfooter

        try:
            instrpricedata = pd_readcsv(
                filename,
                date_index_name=date_time_column,
                date_format=date_format,
                input_column_mapping=input_column_mapping,
                skiprows=skiprows,
                skipfooter=skipfooter,
            )
        except OSError:
            log = futures_contract_object.log(self.log)
            log.warning("Can't find adjusted price file %s" % filename)
            return futuresContractPrices.create_empty()

        instrpricedata = instrpricedata.groupby(level=0).last()

        instrpricedata = futuresContractPrices(instrpricedata)

        return instrpricedata