Ejemplo n.º 1
0
    async def tick(
            self) -> AsyncGenerator[Any, Event]:  # type: ignore[override]
        now = self._start
        for i in range(1000):
            if self._client_order:
                self._client_order.filled = self._client_order.volume
                t = Trade(
                    self._client_order.volume,
                    i,
                    taker_order=self._client_order,
                    maker_orders=[],
                )
                t.taker_order.timestamp = now
                self._client_order = None
                yield Event(type=EventType.TRADE, target=t)
                continue

            o = Order(
                1,
                i,
                Side.BUY,
                self._instrument,
                self.exchange(),
                timestamp=now,
                filled=1,
            )
            t = Trade(1, i, o, [])
            yield Event(type=EventType.TRADE, target=t)
            now += timedelta(minutes=30)
Ejemplo n.º 2
0
    async def tick(self):
        '''return data from exchange'''
        while True:
            # clear order events
            while self._order_event_queue.qsize() > 0:
                order_data = self._order_event_queue.get()
                status = order_data['status']
                order = self._orders[order_data['orderId']]

                if status in ('ApiPending', 'PendingSubmit', 'PendingCancel',
                              'PreSubmitted', 'ApiCancelled', 'Inactive'):
                    # ignore
                    continue

                elif status in ('Submitted', ):
                    # TODO more granular order events api?
                    # ignore
                    pass

                elif status in ('Cancelled', ):
                    e = Event(type=EventType.REJECTED, target=order)
                    yield e

                elif status in ('Filled', ):
                    t = Trade(volume=order_data['filled'],
                              price=order_data['avgFillPrice'],
                              maker_orders=[],
                              taker_order=order)
                    t.my_order = order
                    e = Event(type=EventType.TRADE, target=t)
                    yield e
            await asyncio.sleep(0)
Ejemplo n.º 3
0
Archivo: ib.py Proyecto: galdamour/aat
    async def tick(self):
        '''return data from exchange'''
        while True:
            # clear order events
            while self._order_event_queue.qsize() > 0:
                order_data = self._order_event_queue.get()
                status = order_data['status']
                order = self._orders[order_data['orderId']]

                if status in ('ApiPending', 'PendingSubmit', 'PendingCancel', 'PreSubmitted', 'ApiCancelled', 'Inactive'):
                    # ignore
                    continue

                elif status in ('Submitted',):
                    e = Event(type=EventType.RECEIVED, target=order)
                    yield e

                elif status in ('Cancelled',):
                    e = Event(type=EventType.CANCELED, target=order)
                    yield e

                elif status in ('Filled',):
                    # this is the filled from orderStatus, but we
                    # want to use the one from execDetails

                    # From the IB Docs:
                    # "There are not guaranteed to be orderStatus
                    # callbacks for every change in order status"
                    # It is recommended to use execDetails

                    # ignore
                    pass

                elif status in ('Execution',):
                    # set filled
                    order.filled = order_data['filled']

                    # create trade object
                    t = Trade(volume=order_data['filled'], price=order_data['avgFillPrice'], maker_orders=[], taker_order=order)

                    # set my order
                    t.my_order = order

                    e = Event(type=EventType.TRADE, target=t)
                    yield e

            # clear market data events
            while self._market_data_queue.qsize() > 0:
                market_data = self._market_data_queue.get()
                instrument = market_data['instrument']
                price = market_data['price']
                o = Order(volume=1, price=price, side=Side.BUY, instrument=instrument, exchange=self.exchange())
                t = Trade(volume=1, price=price, taker_order=o, maker_orders=[])
                yield Event(type=EventType.TRADE, target=t)

            await asyncio.sleep(0)
Ejemplo n.º 4
0
Archivo: ib.py Proyecto: bohblue2/aat
    async def tick(self):
        '''return data from exchange'''
        while True:
            # clear order events
            while self._order_event_queue.qsize() > 0:
                order_data = self._order_event_queue.get()
                status = order_data['status']
                order = self._orders[order_data['orderId']]

                if status in ('ApiPending', 'PendingSubmit', 'PendingCancel',
                              'PreSubmitted', 'ApiCancelled', 'Inactive'):
                    # ignore
                    continue

                elif status in ('Submitted', ):
                    # TODO more granular order events api?
                    # ignore
                    pass

                elif status in ('Cancelled', ):
                    e = Event(type=EventType.CANCELED, target=order)
                    yield e

                elif status in ('Filled', ):
                    # set filled
                    order.filled = order_data['filled']

                    # create trade object
                    t = Trade(volume=order_data['filled'],
                              price=order_data['avgFillPrice'],
                              maker_orders=[],
                              taker_order=order)

                    # set my order
                    t.my_order = order

                    e = Event(type=EventType.TRADE, target=t)
                    yield e

            # clear market data events
            while self._market_data_queue.qsize() > 0:
                market_data = self._market_data_queue.get()
                instrument = market_data['instrument']
                price = market_data['price']
                o = Order(volume=1,
                          price=price,
                          side=Side.BUY,
                          instrument=instrument,
                          exchange=self.exchange())
                t = Trade(volume=1,
                          price=price,
                          taker_order=o,
                          maker_orders=[])
                yield Event(type=EventType.TRADE, target=t)

            await asyncio.sleep(0)
Ejemplo n.º 5
0
 async def cancelOrder(self, order: Order):
     '''cancel a previously submitted order to the exchange.'''
     ret = self._client.cancelOrder(order)
     if ret:
         # cancel succesful
         self._order_events.append(
             Event(type=EventType.CANCELED, target=order))
     else:
         # cancel rejected
         self._order_events.append(
             Event(type=EventType.REJECTED, target=order))
Ejemplo n.º 6
0
 async def newOrder(self, order):
     '''submit a new order to the exchange. should set the given order's `id` field to exchange-assigned id'''
     ret = self._client.newOrder(order)
     if ret:
         # order succesful
         self._order_events.append(
             Event(type=EventType.RECEIVED, target=order))
     else:
         # order failure
         self._order_events.append(
             Event(type=EventType.REJECTED, target=order))
Ejemplo n.º 7
0
    async def _onCanceled(self, strategy, order: Order):
        # push event to loop
        ev = Event(type=Event.Types.CANCELED, target=order)
        self._engine.pushTargetedEvent(strategy, ev)

        # synchronize state when engine processes this
        self._alerted_events[ev] = (strategy, order)
Ejemplo n.º 8
0
    async def _onReceived(self, strategy: "Strategy", order: Order) -> None:
        # push event to loop
        ev = Event(type=Event.Types.RECEIVED, target=order)
        self._engine.pushTargetedEvent(strategy, ev)

        # synchronize state when engine processes this
        self._alerted_events[ev] = (strategy, order)
Ejemplo n.º 9
0
    async def newOrder(self, strategy, order: Order):
        '''helper method, defers to buy/sell'''
        # ensure has list
        if strategy not in self._strategy_open_orders:
            self._strategy_open_orders[strategy] = []

        if strategy not in self._strategy_past_orders:
            self._strategy_past_orders[strategy] = []

        if strategy not in self._strategy_trades:
            self._strategy_trades[strategy] = []

        # append to open orders list
        self._strategy_open_orders[strategy].append(order)

        # append to past orders list
        self._strategy_past_orders[strategy].append(order)

        # TODO check risk
        ret, approved = await self._risk_mgr.newOrder(strategy, order)

        # was this trade allowed?
        if approved:
            # send to be executed
            await self._order_mgr.newOrder(strategy, order)
            return ret

        # raise onRejected
        self._engine.pushEvent(Event(type=Event.Types.REJECTED, target=order))
        return None
Ejemplo n.º 10
0
    async def tick(self):
        now = self._start
        for i in range(1000):
            if self._client_order:
                self._client_order.filled = self._client_order.volume
                t = Trade(self._client_order.volume, i, [], self._client_order)
                t.taker_order.timestamp = now
                self._client_order = None
                yield Event(type=EventType.TRADE, target=t)
                continue

            o = Order(1, i, Side.BUY, self._instrument, self.exchange())
            o.filled = 1
            o.timestamp = now
            t = Trade(1, i, [], o)
            yield Event(type=EventType.TRADE, target=t)
            now += timedelta(minutes=30)
Ejemplo n.º 11
0
    async def _onSold(self, strategy, trade: Trade):
        # append to list of trades
        self._strategy_trades[strategy].append(trade)

        # push event to loop
        ev = Event(type=Event.Types.SOLD, target=trade)
        self._engine.pushTargetedEvent(strategy, ev)

        # synchronize state when engine processes this
        self._alerted_events[ev] = (strategy, trade.my_order)
Ejemplo n.º 12
0
    async def _onRejected(self, strategy, order: Order):
        '''callback method for if your order fails to execute

        Args:
            order (Order): the order you attempted to make
        '''
        # push event to loop
        ev = Event(type=Event.Types.REJECTED, target=order)
        self._engine.pushTargetedEvent(strategy, ev)

        # synchronize state when engine processes this
        self._alerted_events[ev] = (strategy, order)
Ejemplo n.º 13
0
    async def tick(self):
        for item in self._data:
            yield Event(EventType.TRADE, item)
            await asyncio.sleep(0)

            # save timestamp
            timestamp = item.timestamp

            while self._queued_orders:
                order = self._queued_orders.popleft()
                order.timestamp = timestamp
                order.filled = order.volume

                t = Trade(
                    volume=order.volume,
                    price=order.price,
                    taker_order=order,
                    maker_orders=[],
                    my_order=order,
                )

                yield Event(type=EventType.TRADE, target=t)
                await asyncio.sleep(0)
Ejemplo n.º 14
0
    async def tick(self):
        '''return data from exchange'''
        dfs = []
        for i in self._subscriptions:
            df = self._client.chartDF(i.name, timeframe='6m')
            df = df[['close', 'volume']]
            df.columns = ['close:{}'.format(i.name), 'volume:{}'.format(i.name)]
            dfs.append(df)

        data = pd.concat(dfs, axis=1)
        data.sort_index(inplace=True)
        data = data.groupby(data.index).last()
        data.drop_duplicates(inplace=True)
        data.fillna(method='ffill', inplace=True)

        for index in data.index:
            for i in self._subscriptions:
                volume = data.loc[index]['volume:{}'.format(i.name)]
                price = data.loc[index]['close:{}'.format(i.name)]

                o = Order(volume=volume, price=price, side=Side.BUY, instrument=i, exchange=self.exchange())
                o.timestamp = index.to_pydatetime()

                t = Trade(volume=volume, price=price, taker_order=o, maker_orders=[])

                yield Event(type=EventType.TRADE, target=t)
                await asyncio.sleep(0)

            while self._queued_orders:
                order = self._queued_orders.popleft()
                order.timestamp = index

                t = Trade(volume=order.volume, price=order.price, taker_order=order, maker_orders=[])
                t.my_order = order

                yield Event(type=EventType.TRADE, target=t)
                await asyncio.sleep(0)
Ejemplo n.º 15
0
    async def _onSold(self, strategy, trade: Trade):
        '''callback method for when/if your order executes.

        Args:
            order_or_trade (Union[Order, Trade]): the trade/s as your order completes, and/or a cancellation order
        '''
        # append to list of trades
        self._strategy_trades[strategy].append(trade)

        # push event to loop
        ev = Event(type=Event.Types.SOLD, target=trade)
        self._engine.pushTargetedEvent(strategy, ev)

        # synchronize state when engine processes this
        self._alerted_events[ev] = (strategy, trade.my_order)
Ejemplo n.º 16
0
    async def onTrade(self, event):
        action, strat, order = False, None, None

        for order in event.target.maker_orders:
            if order.id in self._pending_orders:
                action = True
                _, strat = self._pending_orders[order.id]
                break

        if event.target.taker_order.id in self._pending_orders:
            action = True
            order = event.target.taker_order
            _, strat = self._pending_orders[order.id]

        if action:
            # TODO add to event loop
            event = Event(type=Event.Types.TRADE, target=order)
            if order.side == Order.Sides.SELL:
                await strat.onSold(event)
            else:
                await strat.onBought(event)
            del self._pending_orders[order.id]
Ejemplo n.º 17
0
    async def newOrder(self, order):
        """submit a new order to the exchange. should set the given order's `id` field to exchange-assigned id

        For MarketData-only, can just return None
        """

        # construct IB contract and order
        ibcontract, iborder = _constructContractAndOrder(order)

        # send to IB
        id = self._api.placeOrder(ibcontract, iborder)

        # update order id
        order.id = id
        self._orders[order.id] = order

        # set event for later trigerring
        self._order_received_map[id] = Event()
        await self._order_received_map[id]

        res = self._order_received_res[id]
        del self._order_received_map[id]
        del self._order_received_res[id]
        return res
Ejemplo n.º 18
0
    async def tick(
            self) -> AsyncGenerator[Any, Event]:  # type: ignore[override]
        """return data from exchange"""
        while True:
            # clear order events
            while self._order_event_queue.qsize() > 0:
                order_data = self._order_event_queue.get()
                status = order_data["status"]
                order = self._orders[str(order_data["orderId"])]

                if status in (
                        "ApiPending",
                        "PendingSubmit",
                        "PendingCancel",
                        "PreSubmitted",
                        "ApiCancelled",
                        "Inactive",
                ):
                    # ignore
                    continue

                elif status in ("Submitted", ):
                    self._order_received_res[order.id] = True
                    self._order_received_map[order.id].set()
                    await asyncio.sleep(0)

                elif status in ("Cancelled", ):
                    self._order_cancelled_res[order.id] = True
                    self._order_cancelled_map[order.id].set()
                    await asyncio.sleep(0)

                elif status in ("Filled", ):
                    # this is the filled from orderStatus, but we
                    # want to use the one from execDetails

                    # From the IB Docs:
                    # "There are not guaranteed to be orderStatus
                    # callbacks for every change in order status"
                    # It is recommended to use execDetails

                    # ignore
                    pass

                elif status in ("Execution", ):
                    # set filled
                    order.filled = order_data["filled"]

                    # create trade object
                    t = Trade(
                        volume=order_data["filled"],  # type: ignore
                        price=order_data["avgFillPrice"],  # type: ignore
                        maker_orders=[],
                        taker_order=order,
                    )

                    # set my order
                    t.my_order = order

                    e = Event(type=EventType.TRADE, target=t)
                    yield e

            # clear market data events
            while self._market_data_queue.qsize() > 0:
                market_data = self._market_data_queue.get()
                instrument: Instrument = market_data[
                    "instrument"]  # type: ignore
                price: float = market_data["price"]  # type: ignore
                o = AATOrder(
                    volume=1,
                    price=price,
                    side=Side.BUY,
                    instrument=instrument,
                    exchange=self.exchange(),
                )
                t = Trade(volume=1,
                          price=float(price),
                          taker_order=o,
                          maker_orders=[])
                yield Event(type=EventType.TRADE, target=t)

            await asyncio.sleep(0)
Ejemplo n.º 19
0
    async def tick(self):
        '''return data from exchange'''

        if self._timeframe == 'live':
            data = deque()

            def _callback(record):
                data.append(record)

            self._client.tradesSSE(symbols=",".join(
                [i.name for i in self._subscriptions]),
                                   on_data=_callback)

            while True:
                while data:
                    record = data.popleft()
                    volume = record['volume']
                    price = record['price']
                    instrument = Instrument(record['symbol'],
                                            InstrumentType.EQUITY)

                    o = Order(volume=volume,
                              price=price,
                              side=Side.BUY,
                              instrument=instrument,
                              exchange=self.exchange())
                    t = Trade(volume=volume,
                              price=price,
                              taker_order=o,
                              maker_orders=[])
                    yield Event(type=EventType.TRADE, target=t)

                await asyncio.sleep(0)

        else:
            dfs = []
            insts = set()

            if self._timeframe != '1d':
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    if i.name in insts:
                        # already fetched the data, multiple subscriptions
                        continue

                    if self._cache_data:
                        # first, check if we have this data and its cached already
                        os.makedirs('_aat_data', exist_ok=True)
                        data_filename = os.path.join(
                            '_aat_data', 'iex_{}_{}_{}_{}.pkl'.format(
                                i.name, self._timeframe,
                                datetime.now().strftime('%Y%m%d'),
                                'sand' if self._is_sandbox else ''))

                        if os.path.exists(data_filename):
                            print('using cached IEX data for {}'.format(
                                i.name))
                            df = pd.read_pickle(data_filename)
                        else:
                            df = self._client.chartDF(
                                i.name, timeframe=self._timeframe)
                            df.to_pickle(data_filename)

                    else:
                        df = self._client.chartDF(i.name,
                                                  timeframe=self._timeframe)

                    df = df[['close', 'volume']]
                    df.columns = [
                        'close:{}'.format(i.name), 'volume:{}'.format(i.name)
                    ]
                    dfs.append(df)
                    insts.add(i.name)

                data = pd.concat(dfs, axis=1)
                data.sort_index(inplace=True)
                data = data.groupby(data.index).last()
                data.drop_duplicates(inplace=True)
                data.fillna(method='ffill', inplace=True)

            else:
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    if i.name in insts:
                        # already fetched the data, multiple subscriptions
                        continue

                    date = self._start_date
                    subdfs = []
                    while date <= self._end_date:
                        if self._cache_data:
                            # first, check if we have this data and its cached already
                            os.makedirs('_aat_data', exist_ok=True)
                            data_filename = os.path.join(
                                '_aat_data', 'iex_{}_{}_{}_{}.pkl'.format(
                                    i.name, self._timeframe, date,
                                    'sand' if self._is_sandbox else ''))

                            if os.path.exists(data_filename):
                                print(
                                    'using cached IEX data for {} - {}'.format(
                                        i.name, date))
                                df = pd.read_pickle(data_filename)
                            else:
                                df = self._client.chartDF(
                                    i.name,
                                    timeframe='1d',
                                    date=date.strftime('%Y%m%d'))
                                df.to_pickle(data_filename)
                        else:
                            df = self._client.chartDF(
                                i.name,
                                timeframe='1d',
                                date=date.strftime('%Y%m%d'))

                        if not df.empty:
                            df = df[['average', 'volume']]
                            df.columns = [
                                'close:{}'.format(i.name),
                                'volume:{}'.format(i.name)
                            ]
                            subdfs.append(df)

                        date += timedelta(days=1)

                    dfs.append(pd.concat(subdfs))
                    insts.add(i.name)

                data = pd.concat(dfs, axis=1)
                data.index = [
                    x + timedelta(hours=int(y.split(':')[0]),
                                  minutes=int(y.split(':')[1]))
                    for x, y in data.index
                ]
                data = data.groupby(data.index).last()
                data.drop_duplicates(inplace=True)
                data.fillna(method='ffill', inplace=True)

            for index in data.index:
                for i in self._subscriptions:
                    volume = data.loc[index]['volume:{}'.format(i.name)]
                    price = data.loc[index]['close:{}'.format(i.name)]
                    if volume == 0:
                        continue

                    o = Order(volume=volume,
                              price=price,
                              side=Side.BUY,
                              instrument=i,
                              exchange=self.exchange())
                    o.filled = volume
                    o.timestamp = index.to_pydatetime()

                    t = Trade(volume=volume,
                              price=price,
                              taker_order=o,
                              maker_orders=[])

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)

                while self._queued_orders:
                    order = self._queued_orders.popleft()
                    order.timestamp = index
                    order.filled = order.volume

                    t = Trade(volume=order.volume,
                              price=order.price,
                              taker_order=order,
                              maker_orders=[])
                    t.my_order = order

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)
Ejemplo n.º 20
0
    async def tick(
            self) -> AsyncGenerator[Any, Event]:  # type: ignore[override]
        """return data from exchange"""
        while True:
            # clear order events
            while self._order_event_queue.qsize() > 0:
                try:
                    order_data = self._order_event_queue.get_nowait()
                except Empty:
                    await asyncio.sleep(0.1)
                    continue
                status = order_data["status"]
                order = self._orders[str(order_data["orderId"])]
                if status in (
                        "ApiPending",
                        "PendingSubmit",
                        "PendingCancel",
                        "PreSubmitted",
                        "ApiCancelled",
                ):
                    # ignore
                    continue

                elif status in ("Inactive", ):
                    self._finished_orders.add(order.id)
                    self._send_order_received(order.id, False)
                    self._send_cancel_received(order.id, False)

                elif status in ("Rejected", ):
                    self._finished_orders.add(order.id)
                    self._send_order_received(order.id, False)
                    await asyncio.sleep(0)

                elif status in ("Submitted", ):
                    self._send_order_received(order.id, True)
                    await asyncio.sleep(0)

                elif status in ("Cancelled", ):
                    self._finished_orders.add(order.id)
                    self._send_cancel_received(order.id, True)
                    await asyncio.sleep(0)

                elif status in ("Filled", ):
                    # this is the filled from orderStatus, but we
                    # want to use the one from execDetails

                    # From the IB Docs:
                    # "There are not guaranteed to be orderStatus
                    # callbacks for every change in order status"
                    # It is recommended to use execDetails

                    # ignore
                    pass

                elif status in ("Execution", ):
                    # set filled
                    order.filled = order_data["filled"]

                    # finish order if fully filled
                    if order.finished():
                        self._finished_orders.add(order.id)

                        # if it was cancelled but already executed, clear out the wait
                        self._send_cancel_received(order.id, False)

                    # create trade object
                    t = Trade(
                        volume=order_data["filled"],  # type: ignore
                        price=order_data["avgFillPrice"],  # type: ignore
                        maker_orders=[],
                        taker_order=order,
                    )

                    # set my order
                    t.my_order = order

                    e = Event(type=EventType.TRADE, target=t)

                    # if submitted was skipped, clear out the wait
                    self._send_order_received(order.id, True)
                    yield e

            # clear market data events
            while self._market_data_queue.qsize() > 0:
                try:
                    market_data = self._market_data_queue.get_nowait()
                except Empty:
                    await asyncio.sleep(0.1)
                    continue
                instrument: Instrument = market_data[
                    "instrument"]  # type: ignore
                price: float = market_data["price"]  # type: ignore
                o = AATOrder(
                    volume=1,
                    price=price,
                    side=Side.BUY,
                    instrument=instrument,
                    exchange=self.exchange(),
                    filled=1,
                )
                t = Trade(volume=1,
                          price=float(price),
                          taker_order=o,
                          maker_orders=[])
                yield Event(type=EventType.TRADE, target=t)

            await asyncio.sleep(0)
Ejemplo n.º 21
0
    async def tick(
            self) -> AsyncGenerator[Any, Event]:  # type: ignore[override]
        """return data from exchange"""

        if self._timeframe == "live":
            data: Deque[dict] = deque()

            def _callback(record: dict) -> None:
                data.append(record)

            self._client.tradesSSE(
                symbols=",".join([i.name for i in self._subscriptions]),
                on_data=_callback,
            )

            while True:
                while data:
                    record = data.popleft()
                    volume = record["volume"]
                    price = record["price"]
                    instrument = Instrument(record["symbol"],
                                            InstrumentType.EQUITY)

                    o = Order(
                        volume=volume,
                        price=price,
                        side=Side.BUY,
                        instrument=instrument,
                        exchange=self.exchange(),
                    )
                    t = Trade(volume=volume,
                              price=price,
                              taker_order=o,
                              maker_orders=[])
                    yield Event(type=EventType.TRADE, target=t)

                await asyncio.sleep(0)

        else:
            dfs = []
            insts = set()

            if self._timeframe != "1d":
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    if i.name in insts:
                        # already fetched the data, multiple subscriptions
                        continue

                    if self._cache_data:
                        # first, check if we have this data and its cached already
                        os.makedirs("_aat_data", exist_ok=True)
                        data_filename = os.path.join(
                            "_aat_data",
                            "iex_{}_{}_{}_{}.pkl".format(
                                i.name,
                                self._timeframe,
                                datetime.now().strftime("%Y%m%d"),
                                "sand" if self._is_sandbox else "",
                            ),
                        )

                        if os.path.exists(data_filename):
                            print("using cached IEX data for {}".format(
                                i.name))
                            df = pd.read_pickle(data_filename)
                        else:
                            df = self._client.chartDF(
                                i.name, timeframe=self._timeframe)
                            df.to_pickle(data_filename)

                    else:
                        df = self._client.chartDF(i.name,
                                                  timeframe=self._timeframe)

                    df = df[["close", "volume"]]
                    df.columns = [
                        "close:{}".format(i.name), "volume:{}".format(i.name)
                    ]
                    dfs.append(df)
                    insts.add(i.name)

                data_frame = pd.concat(dfs, axis=1)
                data_frame.sort_index(inplace=True)
                data_frame = data_frame.groupby(data_frame.index).last()
                data_frame.drop_duplicates(inplace=True)
                data_frame.fillna(method="ffill", inplace=True)

            else:
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    if i.name in insts:
                        # already fetched the data, multiple subscriptions
                        continue

                    date = self._start_date
                    subdfs = []
                    while date <= self._end_date:
                        if self._cache_data:
                            # first, check if we have this data and its cached already
                            os.makedirs("_aat_data", exist_ok=True)
                            data_filename = os.path.join(
                                "_aat_data",
                                "iex_{}_{}_{}_{}.pkl".format(
                                    i.name,
                                    self._timeframe,
                                    date,
                                    "sand" if self._is_sandbox else "",
                                ),
                            )

                            if os.path.exists(data_filename):
                                print(
                                    "using cached IEX data for {} - {}".format(
                                        i.name, date))
                                df = pd.read_pickle(data_filename)
                            else:
                                df = self._client.chartDF(
                                    i.name,
                                    timeframe="1d",
                                    date=date.strftime("%Y%m%d"))
                                df.to_pickle(data_filename)
                        else:
                            df = self._client.chartDF(
                                i.name,
                                timeframe="1d",
                                date=date.strftime("%Y%m%d"))

                        if not df.empty:
                            df = df[["average", "volume"]]
                            df.columns = [
                                "close:{}".format(i.name),
                                "volume:{}".format(i.name),
                            ]
                            subdfs.append(df)

                        date += timedelta(days=1)

                    dfs.append(pd.concat(subdfs))
                    insts.add(i.name)

                data_frame = pd.concat(dfs, axis=1)
                data_frame.index = [
                    x + timedelta(hours=int(y.split(":")[0]),
                                  minutes=int(y.split(":")[1]))
                    for x, y in data_frame.index
                ]
                data_frame = data_frame.groupby(data_frame.index).last()
                data_frame.drop_duplicates(inplace=True)
                data_frame.fillna(method="ffill", inplace=True)

            for index in data_frame.index:
                for i in self._subscriptions:
                    volume = data_frame.loc[index]["volume:{}".format(i.name)]
                    price = data_frame.loc[index]["close:{}".format(i.name)]
                    if volume == 0:
                        continue

                    o = Order(
                        volume=volume,
                        price=price,
                        side=Side.BUY,
                        instrument=i,
                        exchange=self.exchange(),
                        filled=volume,
                        timestamp=index.to_pydatetime(),
                    )
                    t = Trade(volume=volume,
                              price=price,
                              taker_order=o,
                              maker_orders=[])

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)

                while self._queued_orders:
                    order = self._queued_orders.popleft()
                    order.timestamp = index
                    order.filled = order.volume

                    t = Trade(
                        volume=order.volume,
                        price=order.price,
                        taker_order=order,
                        maker_orders=[],
                        my_order=order,
                    )

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)
Ejemplo n.º 22
0
 async def tick(self):
     for item in self._data:
         yield Event(EventType.TRADE, item)
Ejemplo n.º 23
0
 async def _onRejected(self, strategy, order):
     # push event to loop
     ev = Event(type=Event.Types.REJECTED, target=order)
     self._engine.pushTargetedEvent(strategy, ev)
Ejemplo n.º 24
0
    async def tick(self):
        '''return data from exchange'''

        if self._timeframe == 'live':
            data = deque()

            def _callback(record):
                data.append(record)

            self._client.tradesSSE(symbols=",".join([i.name for i in self._subscriptions]),
                                   on_data=_callback)

            while True:
                while data:
                    record = data.popleft()
                    volume = record['volume']
                    price = record['price']
                    instrument = Instrument(record['symbol'], InstrumentType.EQUITY)

                    o = Order(volume=volume, price=price, side=Side.BUY, instrument=instrument, exchange=self.exchange())
                    t = Trade(volume=volume, price=price, taker_order=o, maker_orders=[])
                    yield Event(type=EventType.TRADE, target=t)

                await asyncio.sleep(0)

        else:
            dfs = []
            if self._timeframe != '1d':
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    df = self._client.chartDF(i.name, timeframe=self._timeframe)
                    df = df[['close', 'volume']]
                    df.columns = ['close:{}'.format(i.name), 'volume:{}'.format(i.name)]
                    dfs.append(df)

                data = pd.concat(dfs, axis=1)
                data.sort_index(inplace=True)
                data = data.groupby(data.index).last()
                data.drop_duplicates(inplace=True)
                data.fillna(method='ffill', inplace=True)

            else:
                for i in tqdm(self._subscriptions, desc="Fetching data..."):
                    date = self._start_date
                    subdfs = []
                    while date <= self._end_date:
                        df = self._client.chartDF(i.name, timeframe='1d', date=date.strftime('%Y%m%d'))
                        if not df.empty:
                            df = df[['average', 'volume']]
                            df.columns = ['close:{}'.format(i.name), 'volume:{}'.format(i.name)]
                            subdfs.append(df)
                        date += timedelta(days=1)
                    dfs.append(pd.concat(subdfs))

                data = pd.concat(dfs, axis=1)
                data.index = [x + timedelta(hours=int(y.split(':')[0]), minutes=int(y.split(':')[1])) for x, y in data.index]
                data = data.groupby(data.index).last()
                data.drop_duplicates(inplace=True)
                data.fillna(method='ffill', inplace=True)

            for index in data.index:
                for i in self._subscriptions:
                    volume = data.loc[index]['volume:{}'.format(i.name)]
                    price = data.loc[index]['close:{}'.format(i.name)]
                    if volume == 0:
                        continue

                    o = Order(volume=volume, price=price, side=Side.BUY, instrument=i, exchange=self.exchange())
                    o.timestamp = index.to_pydatetime()

                    t = Trade(volume=volume, price=price, taker_order=o, maker_orders=[])

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)

                while self._queued_orders:
                    order = self._queued_orders.popleft()
                    order.timestamp = index

                    t = Trade(volume=order.volume, price=order.price, taker_order=order, maker_orders=[])
                    t.my_order = order

                    yield Event(type=EventType.TRADE, target=t)
                    await asyncio.sleep(0)