Example #1
0
class Pnl(PortfolioAnalyzer):
    Pnl = "Pnl"

    __slots__ = ('pnl_series', 'pnl')

    def __init__(self):
        super(Pnl, self).__init__()

        self.pnl_series = DataSeries(name=Pnl.Pnl, missing_value=0)
        self.pnl = 0

    def update(self, time):
        if self.portfolio.performance_series.size() >= 2:
            self.pnl = self.portfolio.performance_series.get_by_idx(
                -1,
                'total_equity') - self.portfolio.performance_series.get_by_idx(
                    -2, 'total_equity')
            self.pnl_series.add({'timestamp': time, Pnl.Pnl: self.pnl})

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

    def get_series(self):
        return {Pnl.Pnl: self.pnl_series.get_series(Pnl.Pnl)}

    def id(self):
        return '%s.%s' % (self.portfolio.id(), Pnl.Pnl)
 def setUp(self):
     self.time = 9000000000
     self.simluation_clock = SimulationClock()
     self.simluation_clock.reset()
     self.simluation_clock.update_time(self.time)
     self.input = DataSeries()
     self.event_bus = BarAggregatorTest.DummyEventBus()
Example #3
0
class Pnl(PortfolioAnalyzer):
    Pnl = "Pnl"

    __slots__ = (
        'pnl_series',
        'pnl'
    )

    def __init__(self):
        super(Pnl, self).__init__()

        self.pnl_series = DataSeries(name=Pnl.Pnl, missing_value=0)
        self.pnl = 0

    def update(self, time):
        if self.portfolio.performance_series.size() >= 2:
            self.pnl = self.portfolio.performance_series.get_by_idx(-1,
                                                                    'total_equity') - self.portfolio.performance_series.get_by_idx(
                -2, 'total_equity')
            self.pnl_series.add({'timestamp': time, Pnl.Pnl: self.pnl})

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

    def get_series(self):
        return {Pnl.Pnl: self.pnl_series.get_series(Pnl.Pnl)}

    def id(self):
        return '%s.%s' % (self.portfolio.id(), Pnl.Pnl)
Example #4
0
    def test_get_data(self):
        series = DataSeries()

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})
        series.add({"timestamp": self.t2, "v1": 2, "v2": 2})

        self.assertEqual([{'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 1},
                          {'name': "'None'", "timestamp": self.t2, "v1": 2, "v2": 2}], series.get_data())
Example #5
0
    def __create_series(self):
        close = DataSeries("close")

        t = self.t1
        for idx, value in enumerate(self.values):
            close.add({"timestamp": t, "v1": value, "v2": value})
            t = t + datetime.timedelta(0, 3)

        return close
Example #6
0
    def create_series_by_list(valuelist):
        close = DataSeries("close")

        t = datetime.datetime(2000, 1, 1, 11, 34, 59)

        for value in valuelist:
            close.add({"timestamp": t, "v1": value})
            t = t + datetime.timedelta(0, 3)
        return close
Example #7
0
    def __init__(self):
        super(DrawDown, self).__init__()

        self.drawdown_series = DataSeries(name='DrawDown', missing_value=0)
        self.drawdown = 0
        self.drawdown_pct = 0
        self.high_equity = 0
        self.low_equity = 0
        self.current_run_up = 0
        self.current_drawdown = 0
Example #8
0
    def get_name(indicator_name, inputs, input_key, *args):
        parts = []
        parts.extend(DataSeries.convert_to_list(PipeLine.get_input_name(inputs)))

        if input_key:
            parts.extend(DataSeries.convert_to_list(input_key))
        if args:
            parts.extend(args)
        content = ",".join(str(part) for part in parts)
        return '%s(%s)' % (indicator_name, content)
Example #9
0
    def __init__(self, name, inputs, input_keys, length=None, desc=None, **kwargs):
        super(PipeLine, self).__init__(name=name, keys=None, desc=desc, **kwargs)
        # f = lambda i: i \
        #     if isinstance(i, DataSeries) or isinstance(i, Indicator) \
        #     else inst_data_mgr.get_series(i)
        # if isinstance(inputs, list):
        #     self.inputs = [f(i) for i in inputs]
        # else:
        #     self.inputs = f(inputs)

        input_names = []
        self.input_names_and_series = OrderedDict()
        if isinstance(inputs, list):
            for i in inputs:
                if isinstance(i, DataSeries):
                    input_name = DataSeries.get_name(i)
                    input_names.append(input_name)
                    self.input_names_and_series[input_name] = i
                elif isinstance(i, Indicator):
                    input_name = Indicator.get_name(i)
                    input_names.append(input_name)
                    self.input_names_and_series[input_name] = i
                elif isinstance(i, PipeLine):
                    input_name = PipeLine.get_name(i)
                    input_names.append(input_name)
                    self.input_names_and_series[input_name] = i
                else:
                    input_names.append(i)
        else:
            if isinstance(inputs, DataSeries):
                input_name = DataSeries.get_name(inputs)
                input_names.append(input_name)
                self.input_names_and_series[input_name] = inputs
            elif isinstance(inputs, Indicator):
                input_name = Indicator.get_name(inputs)
                input_names.append(input_name)
                self.input_names_and_series[input_name] = inputs
            elif isinstance(inputs, PipeLine):
                input_name = PipeLine.get_name(inputs)
                input_names.append(input_name)
                self.input_names_and_series[input_name] = inputs
            else:
                input_names.append(inputs)

        self.numPipes = len(input_names)
        self.length = length if length is not None else 1
        self.input_names = input_names
        self.input_names_pos = dict(zip(input_names,
                                        range(len(input_names))))

        self.input_keys = self._get_key(input_keys, None)
        # self.calculate = True
        self.__curr_timestamp = None
        self._flush_and_create()
        self.inputs = []
Example #10
0
    def test_init_w_keys(self):
        series = DataSeries(keys=set(["timestamp", "v1"]))

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})

        result = series.get_data()

        self.assertEqual(1, len(result))
        self.assertTrue("timestamp" in result[0])
        self.assertTrue("v1" in result[0])
        self.assertFalse("v2" in result[0])
Example #11
0
    def test_data_series(self, name, serializer):
        item = DataSeries("close", missing_value=0)

        t = datetime.datetime(2000, 1, 1, 11, 34, 59)

        values = [44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
                  45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00]
        for idx, value in enumerate(values):
            item.add({"timestamp": t, "v1": value, "v2": value})
            t = t + datetime.timedelta(0, 3)

        SerializerTest.ser_deser(name, serializer, item)
Example #12
0
    def test_data_series(self, name, serializer):
        item = DataSeries("close", missing_value=0)

        t = datetime.datetime(2000, 1, 1, 11, 34, 59)

        values = [44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
                  45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00]
        for idx, value in enumerate(values):
            item.add({"timestamp": t, "v1": value, "v2": value})
            t = t + datetime.timedelta(0, 3)

        SerializerTest.ser_deser(name, serializer, item)
Example #13
0
    def __init__(self, portf_id="test", cash=1000000, analyzers=None):

        super(Portfolio, self).__init__()
        self.portf_id = portf_id
        self.ord_reqs = {}
        self.orders = {}

        self.performance_series = DataSeries("%s.Performance" % self.portf_id, missing_value=0)
        self.total_equity = 0
        self.cash = cash
        self.stock_value = 0
        self.analyzers = analyzers if analyzers is not None else [Pnl(), DrawDown()]
Example #14
0
    def create_random_walk_series():
        close = DataSeries("close")

        t1 = datetime.datetime(2000, 1, 1, 11, 34, 59)
        t = t1
        w = np.random.normal(0, 1, 1000)
        xs = 100 + np.cumsum(w)

        for value in xs:
            close.add({"timestamp": t, "v1": value, "v2": value})
            t = t + datetime.timedelta(0, 3)
        return close
Example #15
0
    def test_size(self):
        series = DataSeries()
        self.assertEqual(0, series.size())

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

        series.add({"timestamp": self.t2, "v1": 1})
        self.assertEqual(2, series.size())
Example #16
0
    def test_init_w_data(self):

        data_list = [{"timestamp": self.t1, "v1": 1}, {"timestamp": self.t2, "v1": 2}]

        series = DataSeries(keys=set(["timestamp", "v1"]), data_list=data_list)

        self.assertEqual(2, series.size())

        result = series.get_data()

        self.assertEqual(2, len(result))
        self.assertEqual(1, result[0]["v1"])
        self.assertEqual(2, result[1]["v1"])
Example #17
0
    def test_compare_against_oneoff_calculation(self):
        rw = np.cumsum(np.random.normal(0, 2, 1000)) + 100
        close = DataSeries("close")
        close.start(self.app_context)

        t = datetime.datetime.now()
        sma = SMA(close, input_key='close', length=50)
        sma.start(self.app_context)

        result = []

        for x in rw:
            close.add({"timestamp": t, "close": x})
            result.append(sma.now('value'))
            t = t + datetime.timedelta(0, 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)
Example #18
0
    def __init__(self):
        super(DrawDown, self).__init__()

        self.drawdown_series = DataSeries(name='DrawDown', missing_value=0)
        self.drawdown = 0
        self.drawdown_pct = 0
        self.high_equity = 0
        self.low_equity = 0
        self.current_run_up = 0
        self.current_drawdown = 0
Example #19
0
 def get_name(indicator_name, input, input_key, *args):
     if not input:
         return '%s' % indicator_name
     parts = [Indicator.get_input_name(input)]
     if input_key:
         parts.extend(DataSeries.convert_to_list(input_key))
     if args:
         parts.extend(args)
     content = ",".join(str(part) for part in parts)
     return '%s(%s)' % (indicator_name, content)
Example #20
0
 def get_name(indicator_name, input, input_key, *args):
     if not input:
         return '%s' % indicator_name
     parts = [Indicator.get_input_name(input)]
     if input_key:
         parts.extend(DataSeries.convert_to_list(input_key))
     if args:
         parts.extend(args)
     content = ",".join(str(part) for part in parts)
     return '%s(%s)' % (indicator_name, content)
Example #21
0
    def test_add(self):
        series = DataSeries()

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

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})
        series.add({"timestamp": self.t2, "v1": 2, "v2": 2})

        self.assertEqual([{'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 1},
                          {'name': "'None'", "timestamp": self.t2, "v1": 2, "v2": 2}], series.get_data())

        series.add({"timestamp": self.t2, "v1": 3, "v2": 3})

        self.assertEqual([{'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 1},
                          {'name': "'None'", "timestamp": self.t2, "v1": 3, "v2": 3}], series.get_data())

        series.add({"timestamp": self.t3, "v1": 4, "v2": 4})

        self.assertEqual([{'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 1},
                          {'name': "'None'", "timestamp": self.t2, "v1": 3, "v2": 3},
                          {'name': "'None'", "timestamp": self.t3, "v1": 4, "v2": 4}], series.get_data())
Example #22
0
    def test_get_data_dict(self):
        series = DataSeries()

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})
        series.add({"timestamp": self.t2, "v1": 2, "v2": 2})

        self.assertEqual({'name': {str(self.t1): "'None'",  str(self.t2): "'None'"},
                          "timestamp": {str(self.t1): self.t1, str(self.t2): self.t2},
                          "v1": {str(self.t1): 1, str(self.t2): 2},
                          "v2": {str(self.t1): 1, str(self.t2): 2}}, series.get_data_dict())

        self.assertEqual({"v1": {str(self.t1): 1, str(self.t2): 2}, "v2": {str(self.t1): 1, str(self.t2): 2}},
                         series.get_data_dict(['v1', 'v2']))
        self.assertEqual({str(self.t1): 1, str(self.t2): 2}, series.get_data_dict('v1'))
Example #23
0
    def __update_position_qty(self, time, cl_id, inst_id):
        pos = self.get_position(inst_id)
        qty = pos.filled_qty(cl_id)
        inst_id_str = str(inst_id)
        cl_id_str = str(cl_id)

        if cl_id_str in self.cl_position_qty_series_dict:
            pos_qty_series_dict = self.cl_position_qty_series_dict[cl_id_str]
            if inst_id_str in pos_qty_series_dict:
                pos_qty_series_dict[inst_id_str].add({
                    "timestamp": time,
                    "qty": qty
                })
            else:
                series = DataSeries("%s.PosQty" % inst_id, missing_value=0)
                series.add({"timestamp": time, "qty": qty})
                pos_qty_series_dict[inst_id_str] = series
        else:
            pos_qty_series_dict = {}
            series = DataSeries("%s.PosQty" % inst_id, missing_value=0)
            series.add({"timestamp": time, "qty": qty})
            pos_qty_series_dict[inst_id_str] = series
            self.cl_position_qty_series_dict[cl_id_str] = pos_qty_series_dict
Example #24
0
    def __update_position_qty(self, time, cl_id, inst_id):
        pos = self.get_position(inst_id)
        qty = pos.filled_qty(cl_id)
        inst_id_str = str(inst_id)
        cl_id_str = str(cl_id)

        if cl_id_str in self.cl_position_qty_series_dict:
            pos_qty_series_dict = self.cl_position_qty_series_dict[cl_id_str]
            if inst_id_str in pos_qty_series_dict:
                pos_qty_series_dict[inst_id_str].add({"timestamp": time, "qty": qty})
            else:
                series = DataSeries("%s.PosQty" % inst_id, missing_value=0)
                series.add({"timestamp": time, "qty": qty})
                pos_qty_series_dict[inst_id_str] = series
        else:
            pos_qty_series_dict = {}
            series = DataSeries("%s.PosQty" % inst_id, missing_value=0)
            series.add({"timestamp": time, "qty": qty})
            pos_qty_series_dict[inst_id_str] = series
            self.cl_position_qty_series_dict[cl_id_str] = pos_qty_series_dict
Example #25
0
    def __init__(self):
        super(Pnl, self).__init__()

        self.pnl_series = DataSeries(name=Pnl.Pnl, missing_value=0)
        self.pnl = 0
Example #26
0
    def test_current_time(self):
        series = DataSeries()
        self.assertEqual(None, series.current_time())

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})
        self.assertEqual(self.t1, series.current_time())

        series.add({"timestamp": self.t1, "v1": 1, "v2": 1})
        self.assertEqual(self.t1, series.current_time())

        series.add({"timestamp": self.t2, "v1": 2, "v2": 2})
        self.assertEqual(self.t2, series.current_time())
Example #27
0
            else:
                rs = avg_gain / avg_loss
                rsi_value = 100 - 100 / (1 + rs)
                self.__prev_gain = avg_gain
                self.__prev_loss = avg_loss

            result[Indicator.VALUE] = rsi_value
        else:
            result[Indicator.VALUE] = np.nan

        self.add(result)


if __name__ == "__main__":
    import datetime
    from algotrader.utils.time_series import DataSeries

    close = DataSeries("close")
    rsi = RSI(close, input_key='close', length=14)
    print rsi.name
    t = datetime.datetime.now()

    values = [44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
              45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00]

    for idx, value in enumerate(values):
        close.add({'timestamp': t, 'close': value})
        t = t + datetime.timedelta(0, 3)

        print idx, rsi.now()
Example #28
0
    def test_ago(self):
        series = DataSeries()
        self.assertTrue(np.isnan(series.now()))

        series.add({"timestamp": self.t1, "v1": 1, "v2": 2})
        self.assertEqual({'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 2}, series.ago(0))

        series.add({"timestamp": self.t2, "v1": 1.2, "v2": 2.2})
        self.assertEqual({'name': "'None'", "timestamp": self.t2, "v1": 1.2, "v2": 2.2}, series.ago(0))
        self.assertEqual({'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 2}, series.ago(1))

        series.add({"timestamp": self.t3, "v1": 1.3, "v2": 2.3})
        self.assertEqual({'name': "'None'", "timestamp": self.t3, "v1": 1.3, "v2": 2.3}, series.ago(0))
        self.assertEqual({'name': "'None'", "timestamp": self.t2, "v1": 1.2, "v2": 2.2}, series.ago(1))
        self.assertEqual({'name': "'None'", "timestamp": self.t1, "v1": 1, "v2": 2}, series.ago(2))

        series.add({"timestamp": self.t4, "v1": 1.4, "v2": 2.4})
        self.assertEqual({'name': "'None'", "timestamp": self.t4, "v1": 1.4, "v2": 2.4}, series.ago(0))
        self.assertEqual({'name': "'None'", "timestamp": self.t3, "v1": 1.3, "v2": 2.3}, series.ago(1))
        self.assertEqual({'name': "'None'", "timestamp": self.t2, "v1": 1.2, "v2": 2.2}, series.ago(2))
        self.assertEqual({'name': "'None'", "timestamp": self.t1, "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"]))
Example #29
0
class DrawDown(PortfolioAnalyzer):
    DrawDown = "DrawDown"
    DrawDownPct = "DrawDown%"
    HighEquity = "HighEquity"
    LowEquity = "LowEquity"
    CurrentRunUp = "CurrentRunUp"
    CurrentDrawDown = "CurrentDrawDown"

    __slots__ = (
        'drawdown_series',
        'drawdown',
        'drawdown_pct',
        'high_equity',
        'low_equity',
        'current_run_up',
        'current_drawdown',
    )

    def __init__(self):
        super(DrawDown, self).__init__()

        self.drawdown_series = DataSeries(name='DrawDown', missing_value=0)
        self.drawdown = 0
        self.drawdown_pct = 0
        self.high_equity = 0
        self.low_equity = 0
        self.current_run_up = 0
        self.current_drawdown = 0

    def update(self, time):
        total_equity = self.portfolio.total_equity
        if self.portfolio.performance_series.size() == 1:
            self.low_equity = total_equity
            self.high_equity = total_equity
        else:
            if total_equity > self.high_equity:
                self.high_equity = total_equity
                self.low_equity = total_equity
                self.current_drawdown = 0
            elif total_equity < self.low_equity:
                self.low_equity = total_equity
                self.current_run_up = 0
            elif total_equity > self.low_equity and total_equity < self.high_equity:
                self.current_drawdown = 1 - total_equity / self.high_equity
                self.current_run_up = total_equity / self.low_equity - 1

        if self.portfolio.performance_series.size() >= 2:
            self.drawdown = total_equity - self.high_equity

            if self.high_equity != 0:
                self.drawdown_pct = abs(self.drawdown / self.high_equity)
            self.drawdown_series.add({
                'timestamp': time,
                DrawDown.DrawDown: self.drawdown,
                DrawDown.DrawDownPct: self.drawdown_pct
            })

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

    def get_series(self):
        return self.drawdown_series.get_series(
            [self.DrawDown, self.DrawDownPct])

    def id(self):
        return '%s.%s' % (self.portfolio.id(), DrawDown.DrawDown)
Example #30
0
    def test_get_by_idx(self):
        series = DataSeries(keys=set(["timestamp", "v1", "v2"]))

        series.add({"timestamp": self.t1, "v1": 2})
        series.add({"timestamp": self.t2, "v1": 2.4})
        series.add({"timestamp": self.t2, "v2": 3.0})

        # index and key
        self.assertEqual(2, series.get_by_idx(idx=0, keys="v1"))
        self.assertTrue(np.isnan(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": self.t1, "v1": 2, "v2": np.nan}, series.get_by_idx(idx=0))
        self.assertEqual({"timestamp": self.t2, "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 #31
0
class DrawDown(PortfolioAnalyzer):
    DrawDown = "DrawDown"
    DrawDownPct = "DrawDown%"
    HighEquity = "HighEquity"
    LowEquity = "LowEquity"
    CurrentRunUp = "CurrentRunUp"
    CurrentDrawDown = "CurrentDrawDown"

    __slots__ = (
        'drawdown_series',
        'drawdown',
        'drawdown_pct',
        'high_equity',
        'low_equity',
        'current_run_up',
        'current_drawdown',
    )

    def __init__(self):
        super(DrawDown, self).__init__()

        self.drawdown_series = DataSeries(name='DrawDown', missing_value=0)
        self.drawdown = 0
        self.drawdown_pct = 0
        self.high_equity = 0
        self.low_equity = 0
        self.current_run_up = 0
        self.current_drawdown = 0

    def update(self, time):
        total_equity = self.portfolio.total_equity
        if self.portfolio.performance_series.size() == 1:
            self.low_equity = total_equity
            self.high_equity = total_equity
        else:
            if total_equity > self.high_equity:
                self.high_equity = total_equity
                self.low_equity = total_equity
                self.current_drawdown = 0
            elif total_equity < self.low_equity:
                self.low_equity = total_equity
                self.current_run_up = 0
            elif total_equity > self.low_equity and total_equity < self.high_equity:
                self.current_drawdown = 1 - total_equity / self.high_equity
                self.current_run_up = total_equity / self.low_equity - 1

        if self.portfolio.performance_series.size() >= 2:
            self.drawdown = total_equity - self.high_equity

            if self.high_equity != 0:
                self.drawdown_pct = abs(self.drawdown / self.high_equity)
            self.drawdown_series.add({'timestamp': time,
                                      DrawDown.DrawDown: self.drawdown,
                                      DrawDown.DrawDownPct: self.drawdown_pct})

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

    def get_series(self):
        return self.drawdown_series.get_series([self.DrawDown, self.DrawDownPct])

    def id(self):
        return '%s.%s' % (self.portfolio.id(), DrawDown.DrawDown)
Example #32
0
    def test_get_by_time(self):
        series = DataSeries(keys=set(["timestamp", "v1", "v2"]))

        # time and key
        series.add({"timestamp": self.t1, "v1": 2})
        series.add({"timestamp": self.t2, "v1": 2.4})
        series.add({"timestamp": self.t2, "v2": 3.0})

        self.assertEqual(2, series.get_by_time(time=self.t1, keys="v1"))
        self.assertTrue(np.isnan(series.get_by_time(time=self.t1, keys="v2")))
        self.assertEqual(2.4, series.get_by_time(time=self.t2, keys="v1"))
        self.assertEqual(3.0, series.get_by_time(time=self.t2, keys="v2"))
        # time only
        self.assertEqual({"timestamp": self.t1, "v1": 2, "v2": np.nan}, series.get_by_time(time=self.t1))
        self.assertEqual({"timestamp": self.t2, "v1": 2.4, "v2": 3.0}, series.get_by_time(time=self.t2))
Example #33
0
    def test_override_w_same_time(self):
        series = DataSeries(keys=set(["timestamp", "v1", "v2", "v3"]))

        series.add({"timestamp": self.t1, "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(self.t1, "v1"))
        self.assertEqual(3, series.get_by_idx(0, "v2"))
        self.assertEqual(3, series.get_by_time(self.t1, "v2"))
        self.assertTrue(np.isnan(series.get_by_idx(0, "v3")))
        self.assertTrue(np.isnan(series.get_by_time(self.t1, "v3")))

        series.add({"timestamp": self.t1, "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(self.t1, "v1"))
        self.assertEqual(3.4, series.get_by_idx(0, "v2"))
        self.assertEqual(3.4, series.get_by_time(self.t1, "v2"))
        self.assertEqual(1.1, series.get_by_idx(0, "v3"))
        self.assertEqual(1.1, series.get_by_time(self.t1, "v3"))

        series.add({"timestamp": self.t2, "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(self.t1, "v1"))
        self.assertEqual(3.4, series.get_by_idx(0, "v2"))
        self.assertEqual(3.4, series.get_by_time(self.t1, "v2"))
        self.assertEqual(1.1, series.get_by_idx(0, "v3"))
        self.assertEqual(1.1, series.get_by_time(self.t1, "v3"))

        self.assertEqual(2.6, series.get_by_idx(1, "v1"))
        self.assertEqual(2.6, series.get_by_time(self.t2, "v1"))
        self.assertEqual(3.6, series.get_by_idx(1, "v2"))
        self.assertEqual(3.6, series.get_by_time(self.t2, "v2"))
        self.assertTrue(np.isnan(series.get_by_idx(1, "v3")))
        self.assertTrue(np.isnan(series.get_by_time(self.t2, "v3")))
Example #34
0
    def __init__(self):
        super(Pnl, self).__init__()

        self.pnl_series = DataSeries(name=Pnl.Pnl, missing_value=0)
        self.pnl = 0
Example #35
0
class Portfolio(PositionHolder, OrderEventHandler, ExecutionEventHandler, MarketDataEventHandler, AccountEventHandler,
                Persistable, Startable, HasId):
    __slots__ = (
        'portf_id',
        'ord_reqs',
        'orders',
        'app_context',
        'performance_series',
        'total_equity',
        'cash',
        'stock_value',
        'analyzers',
    )

    __transient__ = (
        'ord_reqs',
        'orders',
        'app_context',
    )

    def __init__(self, portf_id="test", cash=1000000, analyzers=None):

        super(Portfolio, self).__init__()
        self.portf_id = portf_id
        self.ord_reqs = {}
        self.orders = {}

        self.performance_series = DataSeries("%s.Performance" % self.portf_id, missing_value=0)
        self.total_equity = 0
        self.cash = cash
        self.stock_value = 0
        self.analyzers = analyzers if analyzers is not None else [Pnl(), DrawDown()]

    def _start(self, app_context, **kwargs):
        self.app_context.portf_mgr.add(self)

        for analyzer in self.analyzers:
            analyzer.set_portfolio(self)
        for order in self.app_context.order_mgr.get_portf_orders(self.id()):
            self._add_order(order)

        for order_req in self.app_context.order_mgr.get_strategy_order_reqs(self.id()):
            self._add_order_req(order_req)

        self.__event_subscription = EventBus.data_subject.subscribe(self.on_next)

    def _stop(self):
        self.__event_subscription.dispose()

    def id(self):
        return self.portf_id

    def all_orders(self):
        return [order for cl_orders in self.orders.values() for order in cl_orders.values()]

    def get_order(self, cl_id, cl_ord_id):
        if cl_id not in self.orders:
            return None
        return self.orders[cl_id].get(cl_ord_id, None)

    def on_bar(self, bar):
        super(Portfolio, self).on_bar(bar)
        self.__update_equity(bar.timestamp, bar.inst_id, bar.close)

    def on_quote(self, quote):
        super(Portfolio, self).on_quote(quote)
        self.__update_equity(quote.timestamp, quote.inst_id, quote.mid())

    def on_trade(self, trade):
        super(Portfolio, self).on_trade(trade)
        self.__update_equity(trade.timestamp, trade.inst_id, trade.price)

    def _add_order(self, order):
        if order.cl_id not in self.orders:
            self.orders[order.cl_id] = {}
        self.orders[order.cl_id][order.cl_ord_id] = order

    def _add_order_req(self, order_req):
        if order_req.cl_id not in self.ord_reqs:
            self.ord_reqs[order_req.cl_id] = {}
        self.ord_reqs[order_req.cl_id][order_req.cl_ord_id] = order_req

    def send_order(self, new_ord_req):
        logger.debug("[%s] %s" % (self.__class__.__name__, new_ord_req))

        if new_ord_req.cl_id in self.ord_reqs and new_ord_req.cl_ord_id in self.ord_reqs[new_ord_req.cl_id]:
            raise RuntimeError("ord_reqs[%s][%s] already exist" % (new_ord_req.cl_id, new_ord_req.cl_ord_id))

        self._add_order_req(new_ord_req)

        order = self.app_context.order_mgr.send_order(new_ord_req)

        self._add_order(order)
        self.get_position(order.inst_id).add_order(order)
        return order

    def cancel_order(self, ord_cancel_req):
        logger.debug("[%s] %s" % (self.__class__.__name__, ord_cancel_req))
        order = self.app_context.order_mgr.cancel_order(ord_cancel_req)
        return order

    def replace_order(self, ord_replace_req):
        logger.debug("[%s] %s" % (self.__class__.__name__, ord_replace_req))
        order = self.app_context.order_mgr.replace_order(ord_replace_req)
        return order

    def on_new_ord_req(self, new_ord_req):
        if new_ord_req.portf_id == self.portf_id:
            self.send_order(new_ord_req)

    def on_ord_cancel_req(self, ord_cancel_req):
        if ord_cancel_req.portf_id == self.portf_id:
            self.cancel_order(ord_cancel_req)

    def on_ord_replace_req(self, ord_replace_req):
        if ord_replace_req.portf_id == self.portf_id:
            self.replace_order(ord_replace_req)

    def on_ord_upd(self, ord_upd):
        if ord_upd.portf_id == self.portf_id:
            logger.debug("[%s] %s" % (self.__class__.__name__, ord_upd))

    def on_exec_report(self, exec_report):
        logger.debug("[%s] %s" % (self.__class__.__name__, exec_report))

        if exec_report.cl_id not in self.ord_reqs and exec_report.cl_ord_id not in self.ord_reqs[exec_report.cl_id]:
            raise Exception("Order not found, ord_reqs[%s][%s]" % (exec_report.cl_id, exec_report.cl_ord_id))

        new_ord_req = self.ord_reqs[exec_report.cl_id][exec_report.cl_ord_id]
        direction = 1 if new_ord_req.action == OrdAction.BUY else -1
        if exec_report.last_qty > 0:
            inst = self.app_context.ref_data_mgr.get_inst(exec_report.inst_id)
            multiplier = inst.factor if inst.type in [InstType.Future, InstType.Option] else 1
            self.cash -= (direction * multiplier* exec_report.last_qty * exec_report.last_price + exec_report.commission)
            self.add_position(exec_report.inst_id, exec_report.cl_id, exec_report.cl_ord_id,
                              direction * exec_report.last_qty)
            self.update_position_price(exec_report.timestamp, exec_report.inst_id, multiplier*exec_report.last_price)

    def update_position_price(self, timestamp, inst_id, price):
        super(Portfolio, self).update_position_price(timestamp, inst_id, price)
        self.__update_equity(timestamp, inst_id, price)
        for analyzer in self.analyzers:
            analyzer.update(timestamp)

    def __update_equity(self, time, inst_id, price):
        self.stock_value = 0
        for position in self.positions.itervalues():
            self.stock_value += position.current_value()
        self.total_equity = self.stock_value + self.cash

        self.performance_series.add(
            {"timestamp": time, "stock_value": self.stock_value, "cash": self.cash, "total_equity": self.total_equity})

    def get_return(self):
        equity = self.performance_series.get_series("total_equity")
        equity.name = 'equity'
        rets = equity.pct_change().dropna()
        # rets.index = rets.index.tz_localize("UTC")
        return rets

    def get_series(self):
        result = self.performance_series.get_series(['stock_value', 'cash', 'total_equity'])

        for analyzer in self.analyzers:
            result.update(analyzer.get_series())
        return result

    def get_result(self):
        result = {
            "TotalEquity": self.total_equity,
            "Cash": self.cash,
            "StockValue": self.stock_value
        }

        for analyzer in self.analyzers:
            result.update(analyzer.get_result())
        return result

    def on_acc_upd(self, acc_upd):
        pass

    def on_portf_upd(self, portf_upd):
        # TODO
        pass
class BarAggregatorTest(TestCase):
    class DummyEventBus:
        def __init__(self):
            self.items = []

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

        def on_next(self, item):
            print 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()
        self.event_bus = BarAggregatorTest.DummyEventBus()

    def update(self, input, data):
        self.simluation_clock.update_time(data.timestamp)
        self.input.add(data.to_dict())

    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()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = 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 = 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(
            Bar(inst_id=1, begin_time=9000000000, timestamp=9000059999, type=1, size=60, open=20, high=20, low=10,
                close=10, vol=400, adj_close=0), 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=BarInputType.Bid)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = 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 = 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 = 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 = 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(
            Bar(inst_id=1, begin_time=9000000000, timestamp=9000059999, type=1, 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=BarInputType.Ask)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = 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 = 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(
            Bar(inst_id=1, begin_time=9000000000, timestamp=9000059999, type=1, 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 = 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(
            Bar(inst_id=1, begin_time=9000060000, timestamp=9000119999, type=1, 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=BarInputType.BidAsk)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 10000
        t = 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 = 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 = 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(
            Bar(inst_id=1, begin_time=9000000000, timestamp=9000059999, type=1, 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=BarInputType.Middle)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 59999
        t = 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(
            Bar(inst_id=1, begin_time=9000000000, timestamp=9000059999, type=1, 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=BarType.Tick, output_size=3)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 60000
        t = 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 = 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 = 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(
            Bar(inst_id=1, begin_time=9000060000, timestamp=9000180000, type=BarType.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=BarType.Volume, output_size=1000)
        agg.start()
        self.assertEqual(0, len(self.event_bus.items))

        self.time += 60000
        t = 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 = 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 = 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(
            Bar(inst_id=1, begin_time=9000060000, timestamp=9000180000, type=BarType.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 = 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(
            Bar(inst_id=1, begin_time=9000180000, timestamp=9000240000, type=BarType.Volume, size=1000, open=10,
                high=50, low=10,
                close=50, vol=1000, adj_close=0), items[0])
        self.assertEqual(
            Bar(inst_id=1, begin_time=9000240000, timestamp=9000240000, type=BarType.Volume, size=1000, open=50,
                high=50, low=50,
                close=50, vol=1000, adj_close=0), items[1])
        self.assertEqual(
            Bar(inst_id=1, begin_time=9000240000, timestamp=9000240000, type=BarType.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 = 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(
            Bar(inst_id=1, begin_time=9000240000, timestamp=9000300000, type=BarType.Volume, size=1000, open=50,
                high=50, low=20,
                close=20, vol=1000, adj_close=0), items[0])
Example #37
0
                rsi_value = 100 - 100 / (1 + rs)
                self.__prev_gain = avg_gain
                self.__prev_loss = avg_loss

            result[Indicator.VALUE] = rsi_value
        else:
            result[Indicator.VALUE] = np.nan

        self.add(result)


if __name__ == "__main__":
    import datetime
    from algotrader.utils.time_series import DataSeries

    close = DataSeries("close")
    rsi = RSI(close, input_key='close', length=14)
    print rsi.name
    t = datetime.datetime.now()

    values = [
        44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42, 45.84, 46.08,
        45.89, 46.03, 45.61, 46.28, 46.28, 46.00
    ]

    for idx, value in enumerate(values):
        close.add({'timestamp': t, 'close': value})
        t = t + datetime.timedelta(0, 3)

        print idx, rsi.now()