Esempio n. 1
0
    def get_history_window(self,
                           assets,
                           end_dt,
                           bar_count,
                           frequency,
                           field,
                           data_frequency=None,
                           is_current=False):
        """
        Public API method that returns a dataframe containing the requested
        history window.  Data is fully adjusted.

        Parameters
        ----------
        assets : list[TradingPair]
            The assets whose data is desired.

        end_dt: datetime
            The date of the last bar

        bar_count: int
            The number of bars desired.

        frequency: string
            "1d" or "1m"

        field: string
            The desired field of the asset.

        data_frequency: string
            The frequency of the data to query; i.e. whether the data is
            'daily' or 'minute' bars.

        is_current: bool
            Skip date filters when current data is requested (last few bars
            until now).

        Notes
        -----
        Catalysts requires an end data with bar count both CCXT wants a
        start data with bar count. Since we have to make calculations here,
        we ensure that the last candle match the end_dt parameter.

        Returns
        -------
        DataFrame
            A dataframe containing the requested data.

        """
        freq, candle_size, unit, data_frequency = get_frequency(
            frequency, data_frequency, supported_freqs=['T', 'D', 'H'])

        # we want to avoid receiving empty candles
        # so we request more than needed
        # TODO: consider defining a const per asset
        # and/or some retry mechanism (in each iteration request more data)
        min_candles_number = get_candles_number_from_minutes(
            unit, candle_size, self.MIN_MINUTES_REQUESTED)

        requested_bar_count = bar_count

        if requested_bar_count < min_candles_number:
            requested_bar_count = min_candles_number

        # The get_history method supports multiple asset
        candles = self.get_candles(
            freq=freq,
            assets=assets,
            bar_count=requested_bar_count,
            end_dt=end_dt if not is_current else None,
        )

        # candles sanity check - verify no empty candles were received:
        for asset in candles:
            if not candles[asset]:
                raise NoCandlesReceivedFromExchange(
                    bar_count=requested_bar_count,
                    end_dt=end_dt,
                    asset=asset,
                    exchange=self.name)

        # for avoiding unnecessary forward fill end_dt is taken back one second
        forward_fill_till_dt = end_dt - timedelta(seconds=1)

        series = get_candles_df(candles=candles,
                                field=field,
                                freq=frequency,
                                bar_count=requested_bar_count,
                                end_dt=forward_fill_till_dt)

        # TODO: consider how to approach this edge case
        # delta_candle_size = candle_size * 60 if unit == 'H' else candle_size
        # Checking to make sure that the dates match
        # delta = get_delta(delta_candle_size, data_frequency)
        # adj_end_dt = end_dt - delta
        # last_traded = asset_series.index[-1]
        # if last_traded < adj_end_dt:
        #    raise LastCandleTooEarlyError(
        #        last_traded=last_traded,
        #        end_dt=adj_end_dt,
        #        exchange=self.name,
        #    )

        df = pd.DataFrame(series)
        df.dropna(inplace=True)

        return df.tail(bar_count)
Esempio n. 2
0
    def get_history_window_for_asset(self,
                                     asset,
                                     end_dt,
                                     bar_count,
                                     frequency,
                                     fields,
                                     data_frequency=None,
                                     is_current=False):
        """
        Public API method that returns a dataframe containing the requested
        history window.  Data is fully adjusted.

        Parameters
        ----------
        asset : TradingPair
            The asset whose data is desired.

        end_dt: datetime
            The date of the last bar

        bar_count: int
            The number of bars desired.

        frequency: string
            "1d" or "1m"

        fields: string
            The desired fields of the asset.

        data_frequency: string
            The frequency of the data to query; i.e. whether the data is
            'daily' or 'minute' bars.

        is_current: bool
            Skip date filters when current data is requested (last few bars
            until now).

        Notes
        -----
        Catalysts requires an end data with bar count both CCXT wants a
        start data with bar count. Since we have to make calculations here,
        we ensure that the last candle match the end_dt parameter.

        Returns
        -------
        DataFrame
            A dataframe containing the requested data.

        """
        freq, candle_size, unit, data_frequency = get_frequency(
            frequency, data_frequency, supported_freqs=['T', 'D', 'H'])

        # we want to avoid receiving empty candles
        # so we request more than needed
        # TODO: consider defining a const per asset
        # and/or some retry mechanism (in each iteration request more data)
        min_candles_number = get_candles_number_from_minutes(
            unit, candle_size, self.MIN_MINUTES_REQUESTED)

        requested_bar_count = bar_count

        if requested_bar_count < min_candles_number:
            requested_bar_count = min_candles_number

        candles = self.get_candles(
            freq=freq,
            assets=
            asset,  # when we pass a single asset, the response is a flat DataFrame with the fields as columns
            bar_count=requested_bar_count,
            end_dt=end_dt if not is_current else None,
        )

        # candles sanity check - verify no empty candles were received:
        if len(candles) == 0:
            raise NoCandlesReceivedFromExchange(bar_count=requested_bar_count,
                                                end_dt=end_dt,
                                                asset=asset,
                                                exchange=self.name)

        # for avoiding unnecessary forward fill end_dt is taken back one second
        forward_fill_till_dt = end_dt - timedelta(seconds=1)

        candles_df = get_candles_df_for_asset(candles=candles,
                                              fields=fields,
                                              freq=frequency,
                                              bar_count=requested_bar_count,
                                              end_dt=forward_fill_till_dt)

        return candles_df.tail(bar_count)