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 connect(self) -> None:
        with open(self._filename) as csvfile:
            self._reader = csv.DictReader(csvfile, delimiter=",")

            for row in self._reader:
                order = Order(
                    volume=float(row["volume"]),
                    price=float(row["close"]),
                    side=Side.BUY,
                    exchange=self.exchange(),
                    instrument=Instrument(
                        row["symbol"].split("-")[0],
                        InstrumentType(row["symbol"].split("-")[1].upper()),
                    ),
                    filled=float(row["volume"]),
                )
                if "time" in row:
                    order.timestamp = datetime.fromtimestamp(float(
                        row["time"]))
                elif "date" in row:
                    order.timestamp = datetime.fromisoformat(row["date"])
                elif "datetime" in row:
                    order.timestamp = datetime.fromisoformat(row["datetime"])

                self._data.append(
                    Trade(
                        volume=float(row["volume"]),
                        price=float(row["close"]),
                        maker_orders=[],
                        taker_order=order,
                    ))
Ejemplo n.º 6
0
    async def connect(self):
        with open(self._filename) as csvfile:
            self._reader = csv.DictReader(csvfile, delimiter=',')

            for row in self._reader:
                order = Order(volume=float(row['volume']),
                              price=float(row['close']),
                              side=Side.BUY,
                              exchange=self.exchange(),
                              instrument=Instrument(
                    row['symbol'].split('-')[0],
                    InstrumentType(row['symbol'].split('-')[1].upper())
                )
                )
                order.filled = float(row['volume'])
                if 'time' in row:
                    order.timestamp = datetime.fromtimestamp(float(row['time']))
                elif 'date' in row:
                    order.timestamp = datetime.fromisoformat(row['date'])
                elif 'datetime' in row:
                    order.timestamp = datetime.fromisoformat(row['datetime'])

                self._data.append(Trade(volume=float(row['volume']),
                                        price=float(row['close']),
                                        maker_orders=[],
                                        taker_order=order))
Ejemplo n.º 7
0
    def restore(self, filename_prefix):
        with open('{}.prices.json'.format(filename_prefix), 'r') as fp:
            jsn = json.load(fp)
            self._prices = {
                Instrument.fromJson(json.loads(k)):
                [(p1, datetime.fromtimestamp(p2)) for p1, p2 in v]
                for k, v in jsn.items()
            }

        with open('{}.trades.json'.format(filename_prefix), 'r') as fp:
            jsn = json.load(fp)
            self._trades = {
                Instrument.fromJson(json.loads(k)):
                [Trade.fromJson(x) for x in v]
                for k, v in jsn.items()
            }

        with open('{}.active_by_inst.json'.format(filename_prefix), 'r') as fp:
            jsn = json.load(fp)
            self._active_positions_by_instrument = {
                Instrument.fromJson(json.loads(k)):
                [Position.fromJson(vv) for vv in v]
                for k, v in jsn.items()
            }

        with open('{}.active_by_strat.json'.format(filename_prefix),
                  'r') as fp:
            jsn = json.load(fp)
            self._active_positions_by_strategy = {
                k: {
                    Instrument.fromJson(json.loads(kk)): Position.fromJson(vv)
                    for kk, vv in v.items()
                }
                for k, v in jsn.items()
            }
Ejemplo n.º 8
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.º 9
0
 def test_maker_orders_validation(self):
     if not os.environ.get('AAT_USE_CPP'):
         with pytest.raises(Exception):
             o = Order(volume=0.0,
                       price=5.0,
                       side=Order.Sides.SELL,
                       order_type=Order.Types.LIMIT,
                       exchange=ExchangeType(''),
                       instrument=_INSTRUMENT)
             Trade(maker_orders=deque(), taker_order=o)
Ejemplo n.º 10
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.º 11
0
 def test_maker_orders_validation(self):
     if not os.environ.get('AAT_USE_CPP'):
         with pytest.raises(pydantic.ValidationError):
             o = Order(id=1,
                       timestamp=datetime.now(),
                       volume=0.0,
                       price=5.0,
                       side=Order.Sides.SELL,
                       order_type=Order.Types.LIMIT,
                       exchange=ExchangeType(''),
                       instrument=_INSTRUMENT)
             Trade(id=1,
                   timestamp=datetime.now(),
                   volume=0.0,
                   price=0.0,
                   side=Order.Sides.SELL,
                   exchange=ExchangeType(''),
                   instrument=_INSTRUMENT,
                   maker_orders=deque(),
                   taker_order=o)
Ejemplo n.º 12
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.º 13
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.º 14
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.º 15
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.º 16
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.º 17
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)