Esempio n. 1
0
    def get_candles(self,
                    freq,
                    assets,
                    bar_count=None,
                    start_dt=None,
                    end_dt=None):
        """
        Supported Intervals
        -------------------
        day, oneMin, fiveMin, thirtyMin, hour

        :param freq:
        :param assets:
        :param bar_count:
        :param start_dt
        :param end_dt
        :return:
        """

        # TODO: this has no effect at the moment
        if end_dt is None:
            end_dt = pd.Timestamp.utcnow()

        log.debug('retrieving {bars} {freq} candles on {exchange} from '
                  '{end_dt} for markets {symbols}, '.format(
                      bars=bar_count,
                      freq=freq,
                      exchange=self.name,
                      end_dt=end_dt,
                      symbols=get_symbols_string(assets)))

        if freq == '1T':
            frequency = 'oneMin'
        elif freq == '5T':
            frequency = 'fiveMin'
        elif freq == '30T':
            frequency = 'thirtyMin'
        elif freq == '60T':
            frequency = 'hour'
        elif freq == '1D':
            frequency = 'day'
        else:
            raise InvalidHistoryFrequencyError(frequency=freq)

        # Making sure that assets are iterable
        asset_list = [assets] if isinstance(assets, TradingPair) else assets
        for asset in asset_list:
            end = int(time.mktime(end_dt.timetuple()))
            url = '{url}/pub/market/GetTicks?marketName={symbol}' \
                  '&tickInterval={frequency}&_={end}'.format(
                url=URL2,
                symbol=self.get_symbol(asset),
                frequency=frequency,
                end=end
            )

            try:
                data = json.loads(urllib.request.urlopen(url).read().decode())
            except Exception as e:
                raise ExchangeRequestError(error=e)

            if data['message']:
                raise ExchangeRequestError(
                    error='Unable to fetch candles {}'.format(data['message']))

            candles = data['result']

            def ohlc_from_candle(candle):
                ohlc = dict(open=candle['O'],
                            high=candle['H'],
                            low=candle['L'],
                            close=candle['C'],
                            volume=candle['V'],
                            price=candle['C'],
                            last_traded=pd.to_datetime(candle['T'], utc=True))
                return ohlc

            ordered_candles = list(reversed(candles))
            ohlc_map = dict()
            if bar_count is None:
                ohlc_map[asset] = ohlc_from_candle(ordered_candles[0])
            else:
                # TODO: optimize
                ohlc_bars = []
                for candle in ordered_candles[:bar_count]:
                    ohlc = ohlc_from_candle(candle)
                    ohlc_bars.append(ohlc)

                ohlc_map[asset] = ohlc_bars

        return ohlc_map[assets] \
            if isinstance(assets, TradingPair) else ohlc_map
Esempio n. 2
0
    def get_candles(self,
                    freq,
                    assets,
                    bar_count=None,
                    start_dt=None,
                    end_dt=None):
        """
        Retrieve OHLVC candles from Bitfinex

        :param data_frequency:
        :param assets:
        :param bar_count:
        :return:

        Available Frequencies
        ---------------------
        '1m', '5m', '15m', '30m', '1h', '3h', '6h', '12h', '1D', '7D', '14D',
         '1M'
        """
        log.debug('retrieving {bars} {freq} candles on {exchange} from '
                  '{end_dt} for markets {symbols}, '.format(
                      bars=bar_count,
                      freq=freq,
                      exchange=self.name,
                      end_dt=end_dt,
                      symbols=get_symbols_string(assets)))

        allowed_frequencies = [
            '1T', '5T', '15T', '30T', '60T', '180T', '360T', '720T', '1D',
            '7D', '14D', '30D'
        ]
        if freq not in allowed_frequencies:
            raise InvalidHistoryFrequencyError(frequency=freq)

        freq_match = re.match(r'([0-9].*)(T|H|D)', freq, re.M | re.I)
        if freq_match:
            number = int(freq_match.group(1))
            unit = freq_match.group(2)

            if unit == 'T':
                if number in [60, 180, 360, 720]:
                    number = number / 60
                    converted_unit = 'h'
                else:
                    converted_unit = 'm'
            else:
                converted_unit = unit

            frequency = '{}{}'.format(number, converted_unit)

        else:
            raise InvalidHistoryFrequencyError(frequency=freq)

        # Making sure that assets are iterable
        asset_list = [assets] if isinstance(assets, TradingPair) else assets
        ohlc_map = dict()
        for asset in asset_list:
            symbol = self._get_v2_symbol(asset)
            url = '{url}/v2/candles/trade:{frequency}:{symbol}'.format(
                url=self.url, frequency=frequency, symbol=symbol)

            if bar_count:
                is_list = True
                url += '/hist?limit={}'.format(int(bar_count))

                def get_ms(date):
                    epoch = datetime.datetime.utcfromtimestamp(0)
                    epoch = epoch.replace(tzinfo=pytz.UTC)

                    return (date - epoch).total_seconds() * 1000.0

                if start_dt is not None:
                    start_ms = get_ms(start_dt)
                    url += '&start={0:f}'.format(start_ms)

                if end_dt is not None:
                    end_ms = get_ms(end_dt)
                    url += '&end={0:f}'.format(end_ms)

            else:
                is_list = False
                url += '/last'

            try:
                self.ask_request()
                response = requests.get(url)
            except Exception as e:
                raise ExchangeRequestError(error=e)

            if 'error' in response.content:
                raise ExchangeRequestError(
                    error='Unable to retrieve candles: {}'.format(
                        response.content))

            candles = response.json()

            def ohlc_from_candle(candle):
                last_traded = pd.Timestamp.utcfromtimestamp(candle[0] / 1000.0)
                last_traded = last_traded.replace(tzinfo=pytz.UTC)
                ohlc = dict(open=np.float64(candle[1]),
                            high=np.float64(candle[3]),
                            low=np.float64(candle[4]),
                            close=np.float64(candle[2]),
                            volume=np.float64(candle[5]),
                            price=np.float64(candle[2]),
                            last_traded=last_traded)
                return ohlc

            if is_list:
                ohlc_bars = []
                # We can to list candles from old to new
                for candle in reversed(candles):
                    ohlc = ohlc_from_candle(candle)
                    ohlc_bars.append(ohlc)

                ohlc_map[asset] = ohlc_bars

            else:
                ohlc = ohlc_from_candle(candles)
                ohlc_map[asset] = ohlc

        return ohlc_map[assets] \
            if isinstance(assets, TradingPair) else ohlc_map
Esempio n. 3
0
    def get_candles(self,
                    freq,
                    assets,
                    bar_count=None,
                    start_dt=None,
                    end_dt=None):
        """
        Retrieve OHLVC candles from Poloniex

        :param freq:
        :param assets:
        :param bar_count:
        :return:

        Available Frequencies
        ---------------------
        '5m', '15m', '30m', '2h', '4h', '1D'
        """

        if end_dt is None:
            end_dt = pd.Timestamp.utcnow()

        log.debug('retrieving {bars} {freq} candles on {exchange} from '
                  '{end_dt} for markets {symbols}, '.format(
                      bars=bar_count,
                      freq=freq,
                      exchange=self.name,
                      end_dt=end_dt,
                      symbols=get_symbols_string(assets)))

        if freq == '1T' and (bar_count == 1 or bar_count is None):
            # TODO: use the order book instead
            # We use the 5m to fetch the last bar
            frequency = 300
        elif freq == '5T':
            frequency = 300
        elif freq == '15T':
            frequency = 900
        elif freq == '30T':
            frequency = 1800
        elif freq == '120T':
            frequency = 7200
        elif freq == '240T':
            frequency = 14400
        elif freq == '1D':
            frequency = 86400
        else:
            # Poloniex does not offer 1m data candles
            # It is likely to error out there frequently
            raise InvalidHistoryFrequencyError(frequency=freq)

        # Making sure that assets are iterable
        asset_list = [assets] if isinstance(assets, TradingPair) else assets
        ohlc_map = dict()

        for asset in asset_list:
            delta = end_dt - pd.to_datetime('1970-1-1', utc=True)
            end = int(delta.total_seconds())

            if bar_count is None:
                start = end - 2 * frequency
            else:
                start = end - bar_count * frequency

            try:
                response = self.api.returnchartdata(self.get_symbol(asset),
                                                    frequency, start, end)
            except Exception as e:
                raise ExchangeRequestError(error=e)

            if 'error' in response:
                raise ExchangeRequestError(
                    error='Unable to retrieve candles: {}'.format(
                        response.content))

            def ohlc_from_candle(candle):
                last_traded = pd.Timestamp.utcfromtimestamp(candle['date'])
                last_traded = last_traded.replace(tzinfo=pytz.UTC)

                ohlc = dict(open=np.float64(candle['open']),
                            high=np.float64(candle['high']),
                            low=np.float64(candle['low']),
                            close=np.float64(candle['close']),
                            volume=np.float64(candle['volume']),
                            price=np.float64(candle['close']),
                            last_traded=last_traded)

                return ohlc

            if bar_count is None:
                ohlc_map[asset] = ohlc_from_candle(response[0])
            else:
                ohlc_bars = []
                for candle in response:
                    ohlc = ohlc_from_candle(candle)
                    ohlc_bars.append(ohlc)
                ohlc_map[asset] = ohlc_bars

        return ohlc_map[assets] \
            if isinstance(assets, TradingPair) else ohlc_map