예제 #1
0
    def test_skipped(self):
        a1 = Asset('FX:EURUSD')
        a2 = Asset('STK:AAPL')
        bars = BarCoordinator([a1, a2], const.Freq.MINUTE5, const.Freq.SECOND5)

        self.assertIsNone(
            bars.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:00:05'), 2, 3, 0, 1)))
        self.assertIsNone(
            bars.update(
                Datum(a2, pd.Timestamp('2019-01-01 12:00:05'), 1, 4, -1, 1)))

        self.assertIsNone(
            bars.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:00:10'), 1, 4, 1, 2)))
        self.assertIsNone(
            bars.update(
                Datum(a2, pd.Timestamp('2019-01-01 12:05:00'), 1, 3, -2, 0)))
        self.assertIn(a2, bars.ready)

        out = bars.update(
            Datum(a1, pd.Timestamp('2019-01-01 12:05:10'), 2, 3, 0, 1))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:05:00'))
        assert_array_equal(out[1], [2, 1])  # open
        assert_array_equal(out[2], [4, 4])  # high
        assert_array_equal(out[3], [0, -2])  # low
        assert_array_equal(out[4], [2, 0])  # close
        self.assertEqual(bars.check, pd.Timestamp('2019-01-01 12:10:00'))
        self.assertEqual(bars.timestamp, pd.Timestamp('2019-01-01 12:10:00'))
        self.assertEqual(bars.data[a1].open, 2)
        self.assertEqual(bars.data[a2].open, None)
예제 #2
0
    def test_offset(self):
        asset = Asset('FX:EURUSD')
        now = pd.Timestamp('2019-01-01 12:00:55')  # start from the last bar
        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5, offset=1)

        # test start
        out = bar.update(Datum(asset, now, 1, 3, 0, 2))
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:01:00'), 1, 3, 0, 2))

        # test update
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:00'), 1, 3, 0, 2)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:01:55'), 6, 9, 4, 5))
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:02:00'), 1, 9, 0, 5))
        self.assertEqual(bar.check, pd.Timestamp.min)
        self.assertIsNone(bar.open)

        # test skip
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:03:00'), 6, 9, 4, 5)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:04:00'), 1, 3, 0, 2))
        self.assertEqual(out,
                         (pd.Timestamp('2019-01-01 12:04:00'), 6, 9, 4, 5))
        self.assertEqual(bar.timestamp, pd.Timestamp('2019-01-01 12:05:00'))
        self.assertEqual(bar.open, 1)
        self.assertEqual(bar.close, 2)
예제 #3
0
    def test_5minute(self):
        asset = Asset('FX:EURUSD')
        bar = DownSampledBar(const.Freq.MINUTE5, const.Freq.SECOND5, offset=1)

        # test start
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:04:55'), 1, 3, 0, 2))
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:05:00'), 1, 3, 0, 2))

        # test update
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:05:00'), 1, 3, 0, 2)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:09:55'), 6, 9, 4, 5))
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:10:00'), 1, 9, 0, 5))
        self.assertEqual(bar.check, pd.Timestamp.min)
        self.assertIsNone(bar.open)

        # test skip
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:10:00'), 6, 9, 4, 5)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:15:00'), 1, 3, 0, 2))
        self.assertEqual(out,
                         (pd.Timestamp('2019-01-01 12:15:00'), 6, 9, 4, 5))
        self.assertEqual(bar.timestamp, pd.Timestamp('2019-01-01 12:20:00'))
        self.assertEqual(bar.open, 1)
        self.assertEqual(bar.close, 2)
예제 #4
0
    def test_start(self):
        now = pd.Timestamp.now()
        print(now)
        data = Datum(Asset('FX:EURUSD'), now, 1, 2, 3, 4)
        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5)
        out = bar.update(data)
        self.assertIsNone(out)
        self.assertEqual(bar.timestamp, now.ceil('1min'),
                         'Internal timestamp should be the ceiling value')
        self.assertEqual(bar.check, now.ceil('1min'),
                         '"Check" timestamp should be the ceiling value')
        self.assertEqual(bar.open, 1)
        self.assertEqual(bar.close, 4)

        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5, 2)
        bar.update(data)
        if now.second > 50:
            self.assertEqual(bar.timestamp,
                             (now + pd.Timedelta(seconds=10)).ceil('1min'),
                             'Offset test wrapped')
            self.assertEqual(bar.check,
                             (now + pd.Timedelta(seconds=10)).ceil('1min') -
                             pd.Timedelta(seconds=10))
        else:
            self.assertEqual(bar.timestamp, now.ceil('1min'), 'Offset test')
            self.assertEqual(bar.check,
                             now.ceil('1min') - pd.Timedelta(seconds=10))

        self.assertEqual(bar.high, 2)
예제 #5
0
    def test_insertion(self):
        asset = Asset('FX:ABC')
        store = DataStore(
            Broker.MOCK,
            Freq.MINUTE)  # tick is not used and for testing purpose
        now = pd.Timestamp.utcnow()

        async def main():
            await store.connect()
            for i in range(5):
                data = Datum(asset, now + pd.Timedelta(minutes=i), 1, 2, 3, 4)
                await store.append(data)
            await store.disconnect()

        asyncio.run(main())

        database = Config['postgres_db']
        user = Config['postgres_user']
        password = Config['postgres_pass']
        port = Config['postgres_port']
        con = pg.connect(database=database,
                         user=user,
                         password=password,
                         host='127.0.0.1',
                         port=port)
        cur = con.cursor()
        cur.execute(f'select * from {store.table_name}')
        res = cur.fetchall()
        self.assertEqual(res[0][1].astimezone(timezone('EST')),
                         now.astimezone(timezone('EST')))
        self.assertIsInstance(res[0][2], datetime)
        self.assertTupleEqual(res[0][3:], (1.0, 2.0, 3.0, 4.0))
        cur.execute(f'drop table {store.table_name}')
        con.commit()
        con.close()
예제 #6
0
    async def process_subscription(self, socket: azmq.Socket):
        """
        Receive request of the form "asset1:ticker1,asset2:ticker2,..."
        Subscribe to the broker
        TODO: add handling for exception. Currently always succeed
        """
        msg = await socket.recv_string(
        )  # format: asset1:ticker1,asset2:ticker2,...
        self.logger.info(f'Receive subscription request on {msg}')

        # filter existing assets
        asset_strings = msg.split(',')
        assets = [Asset(s) for s in asset_strings]
        assets = [asset for asset in assets if asset not in self.subscribed]

        if len(assets) > 0:
            # submit subscription
            await utils.wait_for(self.subscribe(assets),
                                 self.subscription_wait_time,
                                 JobError('Data subscription timeout'))

            # remember newly added subscription
            self.subscribed.update(dict.fromkeys(assets))
            self.logger.info(f'Subscribed: {str(assets)}')

        else:
            self.logger.info(f'No new subscription is needed')

        socket.send_json({'code': const.DCode.Succeeded.value})
예제 #7
0
    def test_offset(self):
        a1 = Asset('FX:EURUSD')
        a2 = Asset('STK:AAPL')
        bars = BarCoordinator([a1, a2], const.Freq.MINUTE5, const.Freq.SECOND5,
                              1)

        self.assertIsNone(
            bars.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:00:00'), 2, 3, 0, 1)))
        self.assertIsNone(
            bars.update(
                Datum(a2, pd.Timestamp('2019-01-01 12:00:00'), 1, 4, -1, 1)))

        self.assertIsNone(
            bars.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:00:05'), 1, 4, 1, 2)))
        self.assertIsNone(
            bars.update(
                Datum(a2, pd.Timestamp('2019-01-01 12:04:55'), 1, 3, -2, 0)))
        self.assertIn(a2, bars.ready)

        out = bars.update(
            Datum(a1, pd.Timestamp('2019-01-01 12:04:55'), 2, 3, 0, 1))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:05:00'))
        assert_array_equal(out[1], [2, 1])  # open
        assert_array_equal(out[2], [4, 4])  # high
        assert_array_equal(out[3], [0, -2])  # low
        assert_array_equal(out[4], [1, 0])  # close
        self.assertIsNone(bars.check)
        assert_array_equal(bars.opens, [np.nan, np.nan])

        # test consecutive bars
        self.assertIsNone(
            bars.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:09:55'), 2, 3, 0, 1)))
        out = bars.update(
            Datum(a2, pd.Timestamp('2019-01-01 12:09:55'), 3, 4, 0, 2))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:10:00'))
        assert_array_equal(out[1], [2, 3])  # open
        assert_array_equal(out[2], [3, 4])  # high
        assert_array_equal(out[3], [0, 0])  # low
        assert_array_equal(out[4], [1, 2])  # close
예제 #8
0
 def test_equity(self):
     a1 = 'STK:AAPL'
     a2 = 'STK:MSFT'
     assets = [Asset(a1), Asset(a2)]
     equity = InMemoryEquityCurve(assets, 10000)
     equity.update(pd.Timestamp('2019-01-01'), {
         a1: [10, 200, 10],
         a2: [100, 50, 5]
     }, np.array([200, 50]))
     equity.update(pd.Timestamp('2019-01-02'), {
         a1: [-5, 250, 5],
         a2: [-80, 45, 5]
     }, np.array([250, 45]))
     equity.update(pd.Timestamp('2019-01-02'), {a1: [-10, 220, 10]},
                   np.array([220, 60]))
     assert_array_equal(equity.market_values,
                        [[0, 0, 10000], [2000, 5000, 3000],
                         [1250, 900, 7850], [-1100, 1200, 10050]])
     assert_array_equal(equity.shares,
                        [[0, 0], [10, 100], [5, 20], [-5, 20]])
     assert_array_equal(equity.commissions,
                        [[0, 0], [10, 5], [5, 5], [10, 0]])
예제 #9
0
    def test_update(self):
        asset = Asset('FX:EURUSD')
        now = pd.Timestamp('2019-01-01 12:01:00')
        data = Datum(asset, now, 1, 2, 3, 4)
        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5)

        # test immediate return
        out = bar.update(data)
        self.assertIsNotNone(out)
        self.assertTupleEqual(out, (now, 1, 2, 3, 4))

        # test regular update
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:05'), 1, 3, 0, 2)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:55'), 1, 6, 0, 2)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:02:00'), 2, 5, 1, 1))
        self.assertEqual(out,
                         (pd.Timestamp('2019-01-01 12:02:00'), 1, 6, 0, 1))
        self.assertEqual(bar.check, pd.Timestamp.min)
        self.assertEqual(bar.open, None)

        # test consecutive update
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:02:05'), 1, 3, 0, 2)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:02:10'), 4, 5, -1,
                      3)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:03:00'), 2, 4, 1, 1))
        self.assertEqual(out,
                         (pd.Timestamp('2019-01-01 12:03:00'), 1, 5, -1, 1))

        # test skip update
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:04:05'), 1, 3, 0, 2)))
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:05:05'), 2, 4, 1,
                  1))  # skip from the 4th minute
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:05:00'), 1, 3, 0, 2))
        self.assertEqual(bar.timestamp, pd.Timestamp('2019-01-01 12:06:00'))
        self.assertEqual(bar.open, 2)
        self.assertEqual(bar.high, 4)
        self.assertEqual(bar.close, 1)
예제 #10
0
    def test_update(self):
        a1 = Asset('FX:EURUSD')
        a2 = Asset('STK:AAPL')
        panel = BarPanel([a1, a2], const.Freq.MINUTE5, const.Freq.SECOND5, 2)

        self.assertIsNone(
            panel.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:05:00'), 1, 2, -1, 0)))
        out = panel.update(
            Datum(a2, pd.Timestamp('2019-01-01 12:05:00'), 1, 2, 0, 1))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:05:00'))
        assert_array_equal(out[1]['open'], [[1, 1]])
        assert_array_equal(out[1]['high'], [[2, 2]])
        assert_array_equal(out[1]['low'], [[-1, 0]])
        assert_array_equal(out[1]['close'], [[0, 1]])

        self.assertIsNone(
            panel.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:10:00'), 2, 3, 0, 1)))
        out = panel.update(
            Datum(a2, pd.Timestamp('2019-01-01 12:10:00'), 1, 2, 0, 1))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:10:00'))
        assert_array_equal(out[1]['open'], [[1, 1], [2, 1]])
        assert_array_equal(out[1]['high'], [[2, 2], [3, 2]])
        assert_array_equal(out[1]['low'], [[-1, 0], [0, 0]])
        assert_array_equal(out[1]['close'], [[0, 1], [1, 1]])

        self.assertIsNone(
            panel.update(
                Datum(a1, pd.Timestamp('2019-01-01 12:15:00'), 2, 3, 0, 1)))
        out = panel.update(
            Datum(a2, pd.Timestamp('2019-01-01 12:15:00'), 1, 2, 0, 1))
        self.assertEqual(out[0], pd.Timestamp('2019-01-01 12:15:00'))
        assert_array_equal(out[1]['open'], [[2, 1], [2, 1]])
        assert_array_equal(out[1]['high'], [[3, 2], [3, 2]])
        assert_array_equal(out[1]['low'], [[0, 0], [0, 0]])
        assert_array_equal(out[1]['close'], [[1, 1], [1, 1]])
예제 #11
0
    async def execute_order(self, socket: azmq.Socket):
        """
        TODO: spawn out task for each request so that we can attend to other requests while waiting for fills
        We need an extra port to do this. Executor also need to provide a port
        For, we handle order sequentially
        """
        struct = await socket.recv_json()  # type: dict
        self.logger.info(f'Receive order: {struct}')

        order = {Asset(k): v for k, v in struct.items() if k != 'Strategy'}
        executions = await self.execute(struct['Strategy'], order)

        self.logger.info(
            f'Executed order for {struct["Strategy"]} {str(executions)}')

        await socket.send_json(executions)
예제 #12
0
    def test_high_water_mark(self):
        asset = Asset('FX:EURUSD')
        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5)

        # test corner case where the starting point is the last bar
        out = bar.update(
            Datum(asset, pd.Timestamp('2019-01-01 12:01:00'), 1, 2, 3, 4))
        self.assertTupleEqual(
            out, (pd.Timestamp('2019-01-01 12:01:00'), 1, 2, 3, 4))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:00'), 1, 2, 3, 4)))
        self.assertEqual(bar.high_water_mark,
                         pd.Timestamp('2019-01-01 12:01:00'))

        # test consecutive update
        bar = DownSampledBar(const.Freq.MINUTE, const.Freq.SECOND5)
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:50'), 1, 2, 3, 4)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:55'), 1, 2, 3, 4)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:01:55'), 1, 10, 0,
                      2)))
        self.assertEqual(bar.high, 2)
        self.assertEqual(bar.low, 3)
        self.assertEqual(bar.close, 4)
        self.assertIsNotNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:02:00'), 1, 2, 3, 4)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:02:00'), 1, 2, 3, 4)))
        self.assertIsNone(
            bar.update(
                Datum(asset, pd.Timestamp('2019-01-01 12:02:05'), 1, 2, 3, 4)))
예제 #13
0
    #     @schedulable()
    #     async def kill(self):
    #         await asyncio.sleep(duration)
    #         raise JobError('Killed')

    def run_controller():
        controller = Controller()
        controller.run()

    def run_data_server():
        # noinspection PyArgumentList
        server = IBDataServer()
        server.run()

    def run_executor():
        time.sleep(1)  # wait for server to start
        executor = Executor(strategy, broker, 10000)
        executor.run()

    threads = [
        threading.Thread(target=func)
        for func in [run_data_server, run_controller, run_executor]
    ]
    [t.start() for t in threads]
    [t.join() for t in threads]


if __name__ == '__main__':
    strat = RandomStrategy([Asset('FX:EURUSD')], const.Freq.MINUTE5, 10000)
    run_servers(IBDataServer, const.Broker.IB, strat, 600)