예제 #1
0
class CandleBuilder(object):
    DEFAULT_CACHE_SIZE = 1000

    def __init__(self, cache_size=None):
        self.required_updates = []
        # they are held here until it is synced with exchange candles timeframe
        self.pending_updates = []
        self.partial_candles = []
        self.cache_size = CandleBuilder.DEFAULT_CACHE_SIZE if cache_size is None else cache_size
        self.candles_list = CircularList(self.cache_size)

    def add_request_update(self, interval, requester):
        if self.candles_list.length(
        ) < interval or interval == 1:  # If interval is 1, we do not need headstart
            self.pending_updates.append(RequestUpdate(interval, requester))
        else:
            request_update = RequestUpdate(interval=interval,
                                           requester=requester)
            headstart_length = self.get_num_candles_for_headstart(interval)
            headstart_candles = self.candles_list.get_last_n_elements(
                headstart_length)
            for candle in headstart_candles:
                request_update.update(candle)
            self.required_updates.append(request_update)

    def remove_request_update(self, requester):
        for update in self.pending_updates:
            if update.requester == requester:
                self.pending_updates.remove(update)
                break

        for update in self.required_updates:
            if update.requester == requester:
                self.required_updates.remove(update)
                break

    def get_num_candles_for_headstart(self, interval):
        last_candle = self.candles_list.get_last_elemet()
        time = datetime.datetime.fromtimestamp(last_candle['open_time'] / 1000)
        minutes = time.hour * 60 + time.minute
        return minutes % interval

    def check_pending_updates(self, candle):
        if len(self.pending_updates) == 0:
            return

        tmp_updates = []
        time = datetime.datetime.fromtimestamp(candle['open_time'] / 1000)
        minutes = time.hour * 60 + time.minute
        for update in self.pending_updates:
            now = datetime.datetime.now()
            if minutes % update.interval == 0:
                tmp_updates.append(update)

        for tmp_update in tmp_updates:
            self.pending_updates.remove(tmp_update)
            self.required_updates.append(tmp_update)

    def on_new_candle(self, candle):
        self.candles_list.add(candle)
        if len(self.partial_candles) == 0:
            self.partial_candles.append(candle)
        self.check_pending_updates(candle)
        for request in self.required_updates:
            request.update(candle)

    def clone(self):
        cloned = CandleBuilder()
        all_candles = self.candles_list.get_ordered_elements()
        for candle in all_candles:
            cloned.candles_list.add(candle)
        for requester in self.pending_updates:
            cloned.pending_updates.append(requester.clone())
        for requester in self.required_updates:
            cloned.required_updates.append(requester.clone())
        return cloned

    def drop_all_requesters(self):
        self.pending_updates = []
        self.required_updates = []

    @staticmethod
    def get_candle_from_arrays(candles, idx):
        candle = dict()
        for candle_key in candles:
            candle[candle_key] = candles[candle_key][idx]
        return candle