Example #1
0
    def test_compare_against_oneoff_calculation(self):
        rw = np.cumsum(np.random.normal(0, 2, 1000)) + 100
        close = DataSeries(time_series=ModelFactory.build_time_series(
            series_id="close"))
        close.start(self.app_context)

        t = 1
        sma = SMA(inputs=close, input_keys='close', length=50)
        sma.start(self.app_context)

        result = []

        for x in rw:
            close.add(timestamp=t, data={"close": x})
            result.append(sma.now('value'))
            t = t + 3

        result = np.array(result)

        # either apply or direct call is equivalent
        target = close.apply('close',
                             start=None,
                             end=None,
                             func=talib.SMA,
                             timeperiod=50)
        # target = talib.SMA(np.array(close.get_series('close')), timeperiod=50)

        result[np.isnan(result)] = 0
        target[np.isnan(target)] = 0

        try:
            np.testing.assert_almost_equal(target, result, 5)
        except AssertionError as e:
            self.fail(e.message)
    def test_get_by_idx(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test", keys=["timestamp", "v1", "v2"])

        series = DataSeries(time_series=ts)

        series.add(data={"timestamp": 0, "v1": 2})
        series.add(data={"timestamp": 1, "v1": 2.4})
        series.add(data={"timestamp": 1, "v2": 3.0})

        # index and key
        self.assertEqual(2, series.get_by_idx(idx=0, keys="v1"))
        self.assertEqual(0.0, series.get_by_idx(idx=0, keys="v2"))
        self.assertEqual(2.4, series.get_by_idx(idx=1, keys="v1"))
        self.assertEqual(3.0, series.get_by_idx(idx=1, keys="v2"))

        # index only
        self.assertEqual({"timestamp": 0, "v1": 2, "v2": 0.0}, series.get_by_idx(idx=0))
        self.assertEqual({"timestamp": 1, "v1": 2.4, "v2": 3.0}, series.get_by_idx(idx=1))

        # test index slice
        series2 = self.create_series_by_list(range(100))
        sliced = series2.get_by_idx(keys='v1', idx=slice(-10, None, None))
        self.assertEqual(len(sliced), 10)

        endPoint = series2.get_by_idx(keys='v1', idx=slice(-1, None, None))
        self.assertEqual(endPoint[0], 99)
Example #3
0
class PnlAnalyzer(Analyzer):
    Pnl = "Pnl"

    def __init__(self, portfolio, state):
        self.portfolio = portfolio
        self.state = state
        self.series = DataSeries(time_series=self.state.pnl.series)

    def update(self, timestamp: int, total_equity: float):
        performance_series = self.portfolio.performance.series

        if self.series.size() >= 2:
            self.state.pnl.last_pnl = performance_series.get_by_idx(-1, PerformanceAnalyzer.TotalEquity) - \
                                      performance_series.get_by_idx(-2, PerformanceAnalyzer.TotalEquity)

            self.series.add(timestamp=timestamp, data={self.Pnl: self.state.pnl.last_pnl})
        else:
            self.state.pnl.last_pnl = 0
            self.series.add(timestamp=timestamp, data={self.Pnl: self.state.pnl.last_pnl})

    def get_result(self):
        return {self.Pnl: self.state.pnl.last_pnl}

    def get_series(self, keys=None):
        keys = keys if keys else self.Pnl
        return {self.Pnl: self.series.get_series(self.Pnl)}

    def last_pnl(self) -> float:
        return self.state.pnl.last_pnl
    def __create_series(self):
        close = DataSeries(time_series=TimeSeries())
        t = 0
        for idx, value in enumerate(self.values):
            close.add(data={"timestamp": t, "v1": value, "v2": value})
            t = t + 3

        return close
    def create_series_by_list(valuelist):
        close = DataSeries(time_series=TimeSeries())

        t = 0

        for value in valuelist:
            close.add(data={"timestamp": t, "v1": value})
            t = t + 3
        return close
Example #6
0
    def create_series_by_list(valuelist):
        close = DataSeries(time_series=ModelFactory.build_time_series(
            series_id="close"))

        t = 1

        for value in valuelist:
            close.add(timestamp=t, data={"v1": value})
            t = t + 3
        return close
    def test_get_data(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test")

        series = DataSeries(time_series=ts)

        series.add(data={"timestamp": 1, "v1": 1, "v2": 1})
        series.add(data={"timestamp": 2, "v1": 2, "v2": 2})

        self.assertEqual([{"timestamp": 1, "v1": 1, "v2": 1},
                          {"timestamp": 2, "v1": 2, "v2": 2}], series.get_data())
Example #8
0
    def __create_plot(self):
        series = DataSeries(time_series=TimeSeries())
        t = 20170101
        for idx, value in enumerate(self.values):
            ts = datestr_to_unixtimemillis(t)
            series.add(timestamp=ts, data={"value": value})
            t = t + 1
        values = series.get_series(["value"])
        plot = TimeSeriesPlot(values)

        return plot
    def test_size(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test")

        series = DataSeries(time_series=ts)
        self.assertEqual(0, series.size())

        series.add(data={"timestamp": 0, "v1": 1})
        self.assertEqual(1, series.size())

        series.add(data={"timestamp": 1, "v1": 1})
        self.assertEqual(2, series.size())
    def create_random_walk_series():
        close = DataSeries(time_series=TimeSeries())

        t1 = 1
        t = t1
        w = np.random.normal(0, 1, 1000)
        xs = 100 + np.cumsum(w)

        for value in xs:
            close.add(data={"timestamp": t, "v1": value, "v2": value})
            t = t + 3
        return close
    def test_init_w_keys(self):

        ts = DataSeriesTest.factory.build_time_series(series_id="test",
                                                      keys=["v1"])

        series = DataSeries(time_series=ts)

        series.add(data={"timestamp": 0, "v1": 1, "v2": 1})

        result = series.get_data()

        self.assertEqual(1, len(result))
        self.assertTrue("v1" in result[0])
        self.assertFalse("v2" in result[0])
    def test_ago(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test")

        series = DataSeries(time_series=ts)
        self.assertEqual(0.0, series.now())

        series.add(data={"timestamp": 0, "v1": 1, "v2": 2})
        self.assertEqual({"timestamp": 0, "v1": 1, "v2": 2}, series.ago(0))

        series.add(data={"timestamp": 1, "v1": 1.2, "v2": 2.2})
        self.assertEqual({"timestamp": 1, "v1": 1.2, "v2": 2.2}, series.ago(0))
        self.assertEqual({"timestamp": 0, "v1": 1, "v2": 2}, series.ago(1))

        series.add(data={"timestamp": 2, "v1": 1.3, "v2": 2.3})
        self.assertEqual({"timestamp": 2, "v1": 1.3, "v2": 2.3}, series.ago(0))
        self.assertEqual({"timestamp": 1, "v1": 1.2, "v2": 2.2}, series.ago(1))
        self.assertEqual({"timestamp": 0, "v1": 1, "v2": 2}, series.ago(2))

        series.add(data={"timestamp": 3, "v1": 1.4, "v2": 2.4})
        self.assertEqual({"timestamp": 3, "v1": 1.4, "v2": 2.4}, series.ago(0))
        self.assertEqual({"timestamp": 2, "v1": 1.3, "v2": 2.3}, series.ago(1))
        self.assertEqual({"timestamp": 1, "v1": 1.2, "v2": 2.2}, series.ago(2))
        self.assertEqual({"timestamp": 0, "v1": 1, "v2": 2}, series.ago(3))

        self.assertEqual({"v1": 1.4, "v2": 2.4}, series.ago(0, ["v1", "v2"]))
        self.assertEqual(1.4, series.ago(0, "v1"))
        self.assertEqual(1.4, series.ago(0, ["v1"]))
    def test_get_data_dict(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test")

        series = DataSeries(time_series=ts)

        series.add(data={"timestamp": 1, "v1": 1, "v2": 1})
        series.add(data={"timestamp": 2, "v1": 2, "v2": 2})

        self.assertEqual({"timestamp": {1: 1, 2: 2},
                          "v1": {1: 1, 2: 2},
                          "v2": {1: 1, 2: 2}}, series.get_data_dict())

        self.assertEqual({"v1": {1: 1, 2: 2}, "v2": {1: 1, 2: 2}},
                         series.get_data_dict(['v1', 'v2']))
        self.assertEqual({1: 1, 2: 2}, series.get_data_dict('v1'))
    def test_get_by_time(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test", keys=["timestamp", "v1", "v2"])

        series = DataSeries(time_series=ts)

        # time and key
        series.add(data={"timestamp": 0, "v1": 2})
        series.add(data={"timestamp": 1, "v1": 2.4})
        series.add(data={"timestamp": 1, "v2": 3.0})

        self.assertEqual(2, series.get_by_time(time=0, keys="v1"))
        self.assertEqual(0.0, series.get_by_time(time=0, keys="v2"))
        self.assertEqual(2.4, series.get_by_time(time=1, keys="v1"))
        self.assertEqual(3.0, series.get_by_time(time=1, keys="v2"))
        # time only
        self.assertEqual({"timestamp": 0, "v1": 2, "v2": 0.0}, series.get_by_time(time=0))
        self.assertEqual({"timestamp": 1, "v1": 2.4, "v2": 3.0}, series.get_by_time(time=1))
Example #15
0
class PerformanceAnalyzer(Analyzer):
    Performance = "Performance"
    StockValue = "stock_value"
    Cash = "cash"
    TotalEquity = "total_equity"

    def __init__(self, portfolio, state):
        self.portfolio = portfolio
        self.state = state
        self.series = DataSeries(time_series=self.state.performance.series)

    def update(self, timestamp: int, total_equity: float):
        self.state.performance.total_equity = total_equity
        self.series.add(timestamp=timestamp,
                        data={
                            self.StockValue: self.state.stock_value,
                            self.Cash: self.state.cash,
                            self.TotalEquity: total_equity
                        })

    def get_result(self):
        return {
            self.StockValue: self.state.stock_value,
            self.Cash: self.state.cash,
            self.TotalEquity: self.state.performance.total_equity
        }

    def get_series(self, keys=None):
        keys = keys if keys else [self.StockValue, self.Cash, self.TotalEquity]
        return self.series.get_series(keys)

    def now(self, key):
        return self.series.now(key)

    def total_equity(self) -> float:
        return self.state.performance.total_equity
    def test_override_w_same_time(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test", keys=["timestamp", "v1", "v2", "v3"])

        series = DataSeries(time_series=ts)

        series.add(data={"timestamp": 1, "v1": 2, "v2": 3})
        self.assertEqual(1, series.size())
        self.assertEqual(2, series.get_by_idx(0, "v1"))
        self.assertEqual(2, series.get_by_time(1, "v1"))
        self.assertEqual(3, series.get_by_idx(0, "v2"))
        self.assertEqual(3, series.get_by_time(1, "v2"))
        self.assertEqual(0.0, series.get_by_idx(0, "v3"))
        self.assertEqual(0.0, series.get_by_time(1, "v3"))

        series.add(data={"timestamp": 1, "v1": 2.4, "v2": 3.4, "v3": 1.1})
        self.assertEqual(1, series.size())
        self.assertEqual(2.4, series.get_by_idx(0, "v1"))
        self.assertEqual(2.4, series.get_by_time(1, "v1"))
        self.assertEqual(3.4, series.get_by_idx(0, "v2"))
        self.assertEqual(3.4, series.get_by_time(1, "v2"))
        self.assertEqual(1.1, series.get_by_idx(0, "v3"))
        self.assertEqual(1.1, series.get_by_time(1, "v3"))

        series.add(data={"timestamp": 2, "v1": 2.6, "v2": 3.6})
        self.assertEqual(2, series.size())
        self.assertEqual(2.4, series.get_by_idx(0, "v1"))
        self.assertEqual(2.4, series.get_by_time(1, "v1"))
        self.assertEqual(3.4, series.get_by_idx(0, "v2"))
        self.assertEqual(3.4, series.get_by_time(1, "v2"))
        self.assertEqual(1.1, series.get_by_idx(0, "v3"))
        self.assertEqual(1.1, series.get_by_time(1, "v3"))

        self.assertEqual(2.6, series.get_by_idx(1, "v1"))
        self.assertEqual(2.6, series.get_by_time(2, "v1"))
        self.assertEqual(3.6, series.get_by_idx(1, "v2"))
        self.assertEqual(3.6, series.get_by_time(2, "v2"))
        self.assertEqual(0.0, series.get_by_idx(1, "v3"))
        self.assertEqual(0.0, series.get_by_time(2, "v3"))
    def test_add(self):
        ts = DataSeriesTest.factory.build_time_series(series_id="test")

        series = DataSeries(time_series=ts)

        self.assertTrue(len(series.get_data()) == 0)

        series.add(data={"timestamp": 0, "v1": 1, "v2": 1})
        series.add(data={"timestamp": 1, "v1": 2, "v2": 2})

        self.assertEqual([{"timestamp": 0, "v1": 1, "v2": 1},
                          {"timestamp": 1, "v1": 2, "v2": 2}], series.get_data())

        series.add(data={"timestamp": 1, "v1": 3, "v2": 3})

        self.assertEqual([{"timestamp": 0, "v1": 1, "v2": 1},
                          {"timestamp": 1, "v1": 3, "v2": 3}], series.get_data())

        series.add(data={"timestamp": 2, "v1": 4, "v2": 4})

        self.assertEqual([{"timestamp": 0, "v1": 1, "v2": 1},
                          {"timestamp": 1, "v1": 3, "v2": 3},
                          {"timestamp": 2, "v1": 4, "v2": 4}], series.get_data())
Example #18
0
class DrawDownAnalyzer(Analyzer):
    DrawDown = "DrawDown"
    DrawDownPct = "DrawDown%"
    HighEquity = "HighEquity"
    LowEquity = "LowEquity"
    CurrentRunUp = "CurrentRunUp"
    CurrentDrawDown = "CurrentDrawDown"

    def __init__(self, portfolio, state):
        self.portfolio = portfolio
        self.state = state
        self.series = DataSeries(time_series=self.state.drawdown.series)

    def update(self, timestamp: int, total_equity: float):
        if self.portfolio.performance.series.size() == 1:
            self.state.drawdown.low_equity = total_equity
            self.state.drawdown.high_equity = total_equity
        else:
            if total_equity > self.state.drawdown.high_equity:
                self.state.drawdown.high_equity = total_equity
                self.state.drawdown.low_equity = total_equity
                self.state.drawdown.current_drawdown = 0
            elif total_equity < self.state.drawdown.low_equity:
                self.state.drawdown.low_equity = total_equity
                self.state.drawdown.current_run_up = 0
            elif total_equity > self.state.drawdown.low_equity and total_equity < self.state.drawdown.high_equity:
                self.state.drawdown.current_drawdown = 1 - total_equity / self.state.drawdown.high_equity
                self.state.drawdown.current_run_up = total_equity / self.state.drawdown.low_equity - 1

        if self.portfolio.performance.series.size() >= 2:
            self.state.drawdown.last_drawdown = total_equity - self.state.drawdown.high_equity

            if self.state.drawdown.high_equity != 0:
                self.state.drawdown.last_drawdown_pct = abs(
                    self.state.drawdown.last_drawdown /
                    self.state.drawdown.high_equity)
            self.series.add(timestamp=timestamp,
                            data={
                                self.DrawDown:
                                self.state.drawdown.last_drawdown,
                                self.DrawDownPct:
                                self.state.drawdown.last_drawdown_pct
                            })

    def get_result(self):
        return {
            self.DrawDown: self.state.drawdown.last_drawdown,
            self.DrawDownPct: self.state.drawdown.last_drawdown_pct,
            self.HighEquity: self.state.drawdown.high_equity,
            self.LowEquity: self.state.drawdown.low_equity,
            self.CurrentRunUp: self.state.drawdown.current_run_up,
            self.CurrentDrawDown: self.state.drawdown.current_drawdown
        }

    def get_series(self, keys=None):
        keys = keys if keys else [self.DrawDown, self.DrawDownPct]
        return self.series.get_series(keys)

    def last_drawdown(self) -> float:
        return self.state.drawdown.last_drawdown

    def last_drawdown_pct(self) -> float:
        return self.state.drawdown.last_drawdown_pct

    def high_equity(self) -> float:
        return self.state.drawdown.high_equity

    def low_equity(self) -> float:
        return self.state.drawdown.low_equity

    def current_run_up(self) -> float:
        return self.state.drawdown.current_run_up

    def current_drawdown(self) -> float:
        return self.state.drawdown.current_drawdown
class BarAggregatorTest(TestCase):
    class DummyEventBus:
        def __init__(self):
            self.items = []

        def reset(self):
            self.items = []

        def on_next(self, item):
            self.items.append(item)

    def setUp(self):
        self.time = 9000000000
        self.simluation_clock = SimulationClock()
        self.simluation_clock.reset()
        self.simluation_clock.update_time(self.time)
        self.input = DataSeries(time_series=TimeSeries())
        self.event_bus = BarAggregatorTest.DummyEventBus()

    def update(self, input, data):
        self.simluation_clock.update_time(data.timestamp)
        dict_data = {k : y for k, y in protobuf_to_dict(data).items() if isinstance(y, (int, float))}
        self.input.add(timestamp=data.timestamp, data=dict_data)

    def test_time_bar_from_trade(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input)
        agg.start(None)
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=20, size=200)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        # expect get a aggregated bar at 9000059999
        self.time += 49999
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=10, size=200)
        self.update(self.input, t)

        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000000000, timestamp=9000059999, type=Bar.Time, size=60, open=20, high=20, low=10,
                close=10, vol=400), items[0])

    def test_time_bar_from_bid(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            input_type=BarAggregationRequest.Bid)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", bid=30, bid_size=100)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", bid=10, bid_size=200)
        self.update(self.input, t)
        self.assertEqual(2, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", bid=70, bid_size=300)
        self.update(self.input, t)
        self.assertEqual(3, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 29998
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", bid=50, bid_size=400)
        self.update(self.input, t)
        self.assertEqual(4, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 3
        self.simluation_clock.update_time(self.time)
        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000000000, timestamp=9000059999, type=Bar.Time, size=60, open=30, high=70, low=10,
                close=50, vol=1000, adj_close=0), items[0])

    def test_time_bar_from_ask(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            input_type=BarAggregationRequest.Ask)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=30, ask_size=100)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 60000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=70, ask_size=300)
        self.update(self.input, t)
        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(1, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000000000, timestamp=9000059999, type=Bar.Time, size=60, open=30, high=30, low=30,
                close=30, vol=100, adj_close=0), items[0])

        self.event_bus.reset()

        self.time += 49999
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=20, ask_size=100)
        self.update(self.input, t)
        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000060000, timestamp=9000119999, type=Bar.Time, size=60, open=70, high=70, low=20,
                close=20, vol=400, adj_close=0), items[0])

    def test_time_bar_from_bidask(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            input_type=BarAggregationRequest.BidAsk)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=30, ask_size=100, bid=0, bid_size=200)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 10000
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=20, ask_size=150, bid=10, bid_size=0)
        self.update(self.input, t)
        self.assertEqual(2, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 39999
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=70, ask_size=300, bid=80, bid_size=10)
        self.update(self.input, t)
        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000000000, timestamp=9000059999, type=Bar.Time, size=60, open=30, high=80, low=20,
                close=80, vol=260, adj_close=0), items[0])

    def test_time_bar_from_mid(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            input_type=BarAggregationRequest.Middle)
        agg.start(None)
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 59999
        t = ModelFactory.build_quote(timestamp=self.time, inst_id="1", ask=30, ask_size=100, bid=18, bid_size=200)
        self.update(self.input, t)
        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000000000, timestamp=9000059999, type=Bar.Time, size=60, open=24, high=24, low=24,
                close=24, vol=150, adj_close=0), items[0])

    def test_tick_bar_from_trade(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            output_bar_type=Bar.Tick, output_size=3)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=20, size=200)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=80, size=100)
        self.update(self.input, t)
        self.assertEqual(2, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=10, size=200)
        self.update(self.input, t)

        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000060000, timestamp=9000180000, type=Bar.Tick, size=3, open=20, high=80,
                low=10,
                close=10, vol=500, adj_close=0), items[0])

    def test_vol_bar_from_trade(self):
        agg = BarAggregator(data_bus=self.event_bus, clock=self.simluation_clock, inst_id="1", input=self.input,
                            output_bar_type=Bar.Volume, output_size=1000)
        agg.start(None)
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=20, size=200)
        self.update(self.input, t)
        self.assertEqual(1, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=80, size=100)
        self.update(self.input, t)
        self.assertEqual(2, agg.count())
        self.assertTrue(len(self.event_bus.items) == 0)

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=10, size=1000)
        self.update(self.input, t)

        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(1, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000060000, timestamp=9000180000, type=Bar.Volume, size=1000, open=20,
                high=80, low=10,
                close=10, vol=1000, adj_close=0), items[0])

        self.event_bus.reset()

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=50, size=2800)
        self.update(self.input, t)

        items = self.event_bus.items
        self.assertEqual(3, len(items))
        self.assertEqual(1, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000180000, timestamp=9000240000, type=Bar.Volume, size=1000, open=10,
                high=50, low=10,
                close=50, vol=1000, adj_close=0), items[0])
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000240000, timestamp=9000240000, type=Bar.Volume, size=1000, open=50,
                high=50, low=50,
                close=50, vol=1000, adj_close=0), items[1])
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000240000, timestamp=9000240000, type=Bar.Volume, size=1000, open=50,
                high=50, low=50,
                close=50, vol=1000, adj_close=0), items[2])

        self.event_bus.reset()

        self.time += 60000
        t = ModelFactory.build_trade(timestamp=self.time, inst_id="1", price=20, size=900)
        self.update(self.input, t)

        items = self.event_bus.items
        self.assertEqual(1, len(items))
        self.assertEqual(0, agg.count())
        self.assertEqual(
            ModelFactory.build_bar(inst_id="1", begin_time=9000240000, timestamp=9000300000, type=Bar.Volume, size=1000, open=50,
                high=50, low=20,
                close=20, vol=1000, adj_close=0), items[0])