Пример #1
0
class RSRS(IndicatorAbstract):
    def __init__(self,
                 _N: int = 30,
                 _use_key: typing.List[str] = ['highprice', 'lowprice'],
                 _idx_key: str = 'time',
                 _ret_key: str = 'rsrs'):
        """
        _N: sample length
        """
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.N = _N

        self.high_buf = deque(maxlen=self.N)
        self.low_buf = deque(maxlen=self.N)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.high_buf.append(_data_struct[self.use_key[0]][-1])
        self.low_buf.append(_data_struct[self.use_key[1]][-1])

        if len(self.high_buf) >= self.N and len(self.low_buf) >= self.N:
            x = np.arange(self.N)
            high_beta = linregress(x, self.high_buf)[0]
            low_beta = linregress(x, self.low_buf)[0]

            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: high_beta - low_beta,
            })
Пример #2
0
class SharpRate(IndicatorAbstract):
    def __init__(
        self,
        _period: int,
        _use_key: str = 'closeprice',
        _idx_key: str = 'time',
        _ret_key: str = 'sharprate',
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.last_price = None
        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price_value = _data_struct[self.use_key][0]
        if self.last_price is not None:
            chg_rate = price_value / self.last_price - 1
            self.buf.append(chg_rate)
            buf_std = statistics.pstdev(self.buf)
            if buf_std != 0:
                self.data.addDict({
                    self.idx_key:
                    index_value,
                    self.ret_key:
                    statistics.mean(self.buf) / buf_std,
                })
        self.last_price = price_value
Пример #3
0
class LogReturn(IndicatorAbstract):
    def __init__(self,
                 _skip_period: int = 1,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'logreturn'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.skip_period = _skip_period
        self.buf = deque(maxlen=self.skip_period)

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        if len(self.buf) >= self.skip_period:
            last_value = self.buf.popleft()
            chg_rate = math.log(value / last_value)
            self.data.addDict({
                self.idx_key: index,
                self.ret_key: chg_rate,
            })
        self.buf.append(value)
Пример #4
0
class EFF(IndicatorAbstract):
    def __init__(self,
                 _period: int,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'eff'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.buf.append(_data_struct.getColumn(self.use_key)[0])
        if len(self.buf) == self.period:
            buf_list = list(self.buf)
            tmp = 0.0
            for a, b in zip(buf_list[:-1], buf_list[1:]):
                tmp += abs(b - a)
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: (self.buf[-1] - self.buf[0]) / tmp,
            })
Пример #5
0
class BIAS(IndicatorAbstract):
    """
    rolling ma
    """
    def __init__(self,
                 _period: int,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'bias'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        self.buf.append(price)
        price_mean = statistics.mean(self.buf)

        self.data.addDict({
            self.idx_key:
            index_value,
            self.ret_key: (price - price_mean) / price_mean * 100,
        })
Пример #6
0
class EMA(IndicatorAbstract):
    def __init__(
            self, _period: int, _use_key: str='closeprice',
            _idx_key: str = 'time', _ret_key: str = 'ema'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        tmp_value = _data_struct[self.use_key][0]
        if len(self) > 0:
            last_ret = self.getLastData().toDict()[self.ret_key]
            tmp_value = (tmp_value - last_ret) / self.period + last_ret
        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: tmp_value,
        })
Пример #7
0
class Kurtosis(IndicatorAbstract):

    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'kurtosis'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.last_price = None
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]
        if self.last_price:
            self.buf.append(math.log(price / self.last_price))
            if len(self.buf) >= self.period:
                self.data.addDict({
                    self.idx_key: index,
                    self.ret_key: kurtosis(self.buf),
                })
        self.last_price = price
Пример #8
0
class ATRConstStop(StopIndicatorAbstract):
    def __init__(
            self,
            _price_data: DataStruct,
            _atr_data: DataStruct,
            _stop_type: int,
            _rate: float = 3,
            _price_use_key: str = 'closeprice',
            _atr_use_key: str = 'atr',
            _idx_key: str = 'time',
            _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_price_data) == 1
        assert len(_atr_data) == 1

        self.stop_type = _stop_type
        self.rate = _rate
        self.price_use_key = _price_use_key
        self.atr_use_key = _atr_use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key,
        )

        price_value = _price_data[self.price_use_key][0]
        atr_value = _atr_data[self.atr_use_key][0]

        if self.stop_type == SignalType.LONG:
            self.stopprice = price_value - self.rate * atr_value
        elif self.stop_type == SignalType.SHORT:
            self.stopprice = price_value + self.rate * atr_value
        else:
            raise Exception('unknown type')

        self._addOne(_price_data)

    def _addOne(
            self, _price_data: DataStruct,
    ):
        self.data.addDict({
            self.idx_key: _price_data.index()[0],
            self.ret_key: self.stopprice,
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct.toDict()[self.price_use_key]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')
Пример #9
0
class STD(IndicatorAbstract):
    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'std'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.buf.append(_data_struct.getColumn(self.use_key)[0])
        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: statistics.pstdev(self.buf),
        })
Пример #10
0
class Diff(IndicatorAbstract):
    def __init__(self,
                 _use_key: str,
                 _init_value: float = None,
                 _idx_key: str = 'time',
                 _ret_key: str = 'diff'):
        """


        :param _use_key:
        :param _init_value: if init_value set, the first ret will be complated, else 0
        :param _idx_key:
        :param _ret_key:
        """
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.last_value = _init_value

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        cur_value = _data_struct[self.use_key][0]
        if self.last_value is not None:
            diff_value = cur_value - self.last_value
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: diff_value,
            })
        self.last_value = cur_value
Пример #11
0
class EFF(IndicatorAbstract):
    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'eff'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.buf.append(_data_struct.getColumn(self.use_key)[0])
        if len(self.buf) == self.period:
            buf_list = list(self.buf)
            tmp = 0.0
            for a, b in zip(buf_list[:-1], buf_list[1:]):
                tmp += abs(b - a)
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: (self.buf[-1] - self.buf[0]) / tmp,
            })
Пример #12
0
class BIAS(IndicatorAbstract):
    """
    rolling ma
    """

    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'bias'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        self.buf.append(price)
        price_mean = statistics.mean(self.buf)

        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: (price - price_mean) / price_mean * 100,
        })
Пример #13
0
class Kurtosis(IndicatorAbstract):
    def __init__(self,
                 _period: int,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'kurtosis'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.last_price = None
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]
        if self.last_price:
            self.buf.append(math.log(price / self.last_price))
            if len(self.buf) >= self.period:
                self.data.addDict({
                    self.idx_key: index,
                    self.ret_key: kurtosis(self.buf),
                })
        self.last_price = price
Пример #14
0
class LogReturn(IndicatorAbstract):
    def __init__(
            self,
            _skip_period: int = 1,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'logreturn'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.skip_period = _skip_period
        self.buf = deque(maxlen=self.skip_period)

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        if len(self.buf) >= self.skip_period:
            last_value = self.buf.popleft()
            chg_rate = math.log(value / last_value)
            self.data.addDict({
                self.idx_key: index,
                self.ret_key: chg_rate,
            })
        self.buf.append(value)
Пример #15
0
    def getSettlementData(self):
        tmp = DataStruct(['tradingday', 'fund', 'commission', 'margin'],
                         'tradingday')
        for d in self.settlement_record:
            tmp.addDict(d)

        return tmp
Пример #16
0
class MAX(IndicatorAbstract):
    """
    rolling simple ma
    """

    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'max'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.buf.append(_data_struct.getColumn(self.use_key)[0])
        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: max(self.buf),
        })
Пример #17
0
class SharpRate(IndicatorAbstract):
    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'sharprate',
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.last_price = None
        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price_value = _data_struct[self.use_key][0]
        if self.last_price is not None:
            chg_rate = price_value / self.last_price - 1
            self.buf.append(chg_rate)
            buf_std = statistics.pstdev(self.buf)
            if buf_std != 0:
                self.data.addDict({
                    self.idx_key: index_value,
                    self.ret_key: statistics.mean(self.buf) / buf_std,
                })
        self.last_price = price_value
Пример #18
0
class FastVolatility(IndicatorAbstract):
    def __init__(
            self, _period: int,
            _factor: int = 1,
            _smooth: int = 1,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'volatility',
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.last_price = None
        self.period = _period
        self.factor = math.sqrt(_factor)
        self.smooth = _smooth

        self.buf = deque(maxlen=self.period)
        self.mean = 0.0
        self.sum_of_pow = 0.0

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price_value = _data_struct[self.use_key][0]
        if self.last_price is not None:
            chg_rate = price_value / self.last_price - 1

            if len(self.buf) >= self.period:
                last_value = self.buf.popleft()
                self.buf.append(chg_rate)
                self.sum_of_pow += chg_rate ** 2
                self.sum_of_pow -= last_value ** 2
                self.mean += (chg_rate - last_value) / self.period
            else:
                n = len(self.buf)
                self.buf.append(chg_rate)
                self.sum_of_pow += chg_rate ** 2
                self.mean = (self.mean * n + chg_rate) / len(self.buf)

            var = self.sum_of_pow / len(self.buf) - self.mean ** 2
            std_value = math.sqrt(max(0.0, var)) * self.factor
            if self.smooth > 1 and len(self.data):
                last_std_value = self.data[self.ret_key][-1]
                std_value = (
                    (self.smooth - 1) * last_std_value + std_value
                ) / self.smooth

            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: std_value,
            })
        self.last_price = price_value
Пример #19
0
    def settlement(self, _backtest_key) -> DataStruct:
        settlement_list = self.fetchSettlementRecords(_backtest_key)
        keys = ['tradingday', 'type', 'fund', 'commission', 'margin']
        ret = DataStruct(keys, 'tradingday')
        for d in settlement_list:
            ret.addDict(d)

        return ret
Пример #20
0
    def getSignalData(self):
        tmp = DataStruct(
            ['strategy', 'tradingday', 'datetime', 'symbol', 'strength'],
            'datetime')
        for d in self.signal_record:
            tmp.addDict(d)

        return tmp
Пример #21
0
class FastVolatility(IndicatorAbstract):
    def __init__(
        self,
        _period: int,
        _factor: int = 1,
        _smooth: int = 1,
        _use_key: str = 'closeprice',
        _idx_key: str = 'time',
        _ret_key: str = 'volatility',
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.last_price = None
        self.period = _period
        self.factor = math.sqrt(_factor)
        self.smooth = _smooth

        self.buf = deque(maxlen=self.period)
        self.mean = 0.0
        self.sum_of_pow = 0.0

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price_value = _data_struct[self.use_key][0]
        if self.last_price is not None:
            chg_rate = price_value / self.last_price - 1

            if len(self.buf) >= self.period:
                last_value = self.buf.popleft()
                self.buf.append(chg_rate)
                self.sum_of_pow += chg_rate**2
                self.sum_of_pow -= last_value**2
                self.mean += (chg_rate - last_value) / self.period
            else:
                n = len(self.buf)
                self.buf.append(chg_rate)
                self.sum_of_pow += chg_rate**2
                self.mean = (self.mean * n + chg_rate) / len(self.buf)

            std_value = math.sqrt(self.sum_of_pow / len(self.buf) -
                                  self.mean**2) * self.factor
            if self.smooth > 1 and len(self.data):
                last_std_value = self.data[self.ret_key][-1]
                std_value = ((self.smooth - 1) * last_std_value +
                             std_value) / self.smooth

            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: std_value,
            })
        self.last_price = price_value
Пример #22
0
class RateConstStop(StopIndicatorAbstract):
    def __init__(
            self,
            _data: DataStruct,
            _stop_type: int,
            _stop_rate: float = 0.05,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_data) == 1

        self.stop_type = _stop_type
        self.stop_rate = _stop_rate
        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        price = _data[self.use_key][0]
        if self.stop_type == SignalType.LONG:
            stop_price = price * (1 - self.stop_rate)
        elif self.stop_type == SignalType.SHORT:
            stop_price = price * (1 + self.stop_rate)
        else:
            raise Exception('unknown type')
        time = _data.index()[0]

        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key,
            [[time, stop_price]]
        )

    def _addOne(self, _data_struct: DataStruct):
        stop_price = self.data[self.ret_key][-1]
        time = _data_struct.index()[0]

        self.data.addDict({
            self.idx_key: time,
            self.ret_key: stop_price,
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct[self.use_key][0]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')
Пример #23
0
    def settlement(self, _backtest_key) -> DataStruct:
        settlement_list = self.fetchSettlementRecords(_backtest_key)
        keys = [
            'tradingday', 'type',
            'fund', 'commission', 'margin'
        ]
        ret = DataStruct(keys, 'tradingday')
        for d in settlement_list:
            ret.addDict(d)

        return ret
Пример #24
0
    def getFillData(self):
        tmp = DataStruct([
            'strategy', 'tradingday', 'datetime', 'symbol', 'index', 'action',
            'direction', 'price', 'quantity', 'commission'
        ], 'datetime')
        for d in self.fill_record:
            d = copy(d)
            d['action'] = ActionType.toStr(d['action'])
            d['direction'] = DirectionType.toStr(d['direction'])
            tmp.addDict(d)

        return tmp
Пример #25
0
class AdaKalman(IndicatorAbstract):
    def __init__(
        self, _ada_period: int=30,
        _init_x: float = 0.0, _init_P: float =1.0,
        _init_R: float = 0.1 ** 2, _init_Q: float = 0.01 ** 2,
        _use_key: str = 'closeprice',
        _idx_key: str = 'time', _ret_key: str = 'kalman'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.ada_period = _ada_period
        self.value_std = FastSTD(_ada_period, _use_key=self.use_key)
        self.x_std = FastSTD(_ada_period, _use_key='x')

        self.R = _init_R
        self.Q = _init_Q

        self.x = _init_x
        self.P = _init_P

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        self.value_std.addOne(_data_struct)

        if len(self.value_std) > 1:
            self.R = self.value_std.getLastData()['std'][0] ** 2
        if len(self.x_std) > 1:
            self.Q = self.x_std.getLastData()['std'][0] ** 2

        # predict
        # self.x += 0.0  # x assume not changed
        self.P += self.Q

        # update
        k = self.P / (self.P + self.R)
        x_diff_value = k * (value - self.x)
        self.x += x_diff_value
        self.P = (1 - k) * self.P

        self.data.addDict({
            self.idx_key: index,
            self.ret_key: self.x
        })
Пример #26
0
class RateConstStop(StopIndicatorAbstract):
    def __init__(
        self,
        _data: DataStruct,
        _stop_type: int,
        _stop_rate: float = 0.05,
        _use_key: str = 'closeprice',
        _idx_key: str = 'time',
        _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_data) == 1

        self.stop_type = _stop_type
        self.stop_rate = _stop_rate
        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        price = _data[self.use_key][0]
        if self.stop_type == SignalType.LONG:
            stop_price = price * (1 - self.stop_rate)
        elif self.stop_type == SignalType.SHORT:
            stop_price = price * (1 + self.stop_rate)
        else:
            raise Exception('unknown type')
        time = _data.index()[0]

        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key,
                               [[time, stop_price]])

    def _addOne(self, _data_struct: DataStruct):
        stop_price = self.data[self.ret_key][-1]
        time = _data_struct.index()[0]

        self.data.addDict({
            self.idx_key: time,
            self.ret_key: stop_price,
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct[self.use_key][0]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')
Пример #27
0
    def getOrderData(self):
        tmp = DataStruct([
            'strategy', 'tradingday', 'datetime', 'symbol', 'index',
            'order_type', 'action', 'direction', 'quantity', 'price'
        ], 'datetime')
        for d in self.order_record:
            d = copy(d)
            d['order_type'] = OrderType.toStr(d['order_type'])
            d['action'] = ActionType.toStr(d['action'])
            d['direction'] = DirectionType.toStr(d['direction'])
            tmp.addDict(d)

        return tmp
Пример #28
0
class CCI(IndicatorAbstract):
    """
    rolling ma
    """

    def __init__(
            self, _period: int, _constant: float = 0.15,
            _close_key: str = 'closeprice',
            _high_key: str = 'highprice',
            _low_key: str = 'lowprice',
            _idx_key: str = 'time', _ret_key: str = 'cci',
    ):
        super().__init__()

        self.close_key = _close_key
        self.high_key = _high_key
        self.low_key = _low_key

        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.constant = _constant
        self.tp_buf = deque(maxlen=self.period)
        self.dev_buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        close_price = _data_struct[self.close_key][0]
        high_price = _data_struct[self.high_key][0]
        low_price = _data_struct[self.low_key][0]

        tp = (close_price + high_price + low_price) / 3
        if len(self.tp_buf) == 0:
            dev = high_price - low_price
        else:
            dev = abs(tp - self.tp_buf[-1])
        self.tp_buf.append(tp)
        self.dev_buf.append(dev)

        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: (tp - statistics.mean(self.tp_buf)) / (
                self.constant * statistics.mean(self.dev_buf)
            ),
        })
Пример #29
0
class SimMA(IndicatorAbstract):
    EMPTY = 0
    LONG = 1
    SHORT = 2

    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'simma'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.value = 1.0
        self.last_price = None
        self.last_status = self.EMPTY

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        self.buf.append(price)
        ma_value = sum(self.buf) / len(self.buf)

        if self.last_status == self.LONG:
            self.value *= price / self.last_price
        if self.last_status == self.SHORT:
            self.value /= price / self.last_price

        self.data.addDict({
            self.idx_key: index,
            self.ret_key: self.value,
        })

        if price > ma_value:
            self.last_status = self.LONG
        elif price < ma_value:
            self.last_status = self.SHORT
        else:
            self.last_status = self.EMPTY
        self.last_price = price
Пример #30
0
class CCI(IndicatorAbstract):
    """
    rolling ma
    """
    def __init__(
        self,
        _period: int,
        _constant: float = 0.15,
        _close_key: str = 'closeprice',
        _high_key: str = 'highprice',
        _low_key: str = 'lowprice',
        _idx_key: str = 'time',
        _ret_key: str = 'cci',
    ):
        super().__init__()

        self.close_key = _close_key
        self.high_key = _high_key
        self.low_key = _low_key

        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.constant = _constant
        self.tp_buf = deque(maxlen=self.period)
        self.dev_buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        close_price = _data_struct[self.close_key][0]
        high_price = _data_struct[self.high_key][0]
        low_price = _data_struct[self.low_key][0]

        tp = (close_price + high_price + low_price) / 3
        if len(self.tp_buf) == 0:
            dev = high_price - low_price
        else:
            dev = abs(tp - self.tp_buf[-1])
        self.tp_buf.append(tp)
        self.dev_buf.append(dev)

        self.data.addDict({
            self.idx_key:
            index_value,
            self.ret_key: (tp - statistics.mean(self.tp_buf)) /
            (self.constant * statistics.mean(self.dev_buf)),
        })
Пример #31
0
class ReturnRate(IndicatorAbstract):
    def __init__(
            self,
            _smooth_period: int = 1,
            _skip_period: int = 1,
            _use_abs: bool=False,
            _use_percent: bool=False,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'returnrate'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.skip_period = _skip_period
        self.smooth_period = _smooth_period
        self.buf = deque(maxlen=self.skip_period)
        self.last_rate = None

        self.use_abs = _use_abs
        self.use_percent = _use_percent

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        if len(self.buf) >= self.skip_period:
            last_value = self.buf.popleft()
            chg_rate = value / last_value - 1
            if self.use_abs:
                chg_rate = abs(chg_rate)
            if self.use_percent:
                chg_rate *= 100.0
            if self.last_rate is None:
                self.last_rate = chg_rate
            else:
                self.last_rate = (chg_rate - self.last_rate) / \
                    self.smooth_period + self.last_rate
            self.data.addDict({
                self.idx_key: index,
                self.ret_key: self.last_rate
            })
        self.buf.append(value)
Пример #32
0
class FastSTD(IndicatorAbstract):
    def __init__(
            self, _period: int, _ignore_mean: bool = False,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'std'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.sum_of_pow = 0.0
        self.mean = 0.0

        self.period = _period
        self.ignore_mean = _ignore_mean
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        value = _data_struct[self.use_key][0]
        index = _data_struct.index()[0]
        if len(self.buf) >= self.period:
            last_value = self.buf.popleft()
            self.buf.append(value)
            self.sum_of_pow += value ** 2
            self.sum_of_pow -= last_value ** 2
            if not self.ignore_mean:
                self.mean += (value - last_value) / self.period
        else:
            n = len(self.buf)
            self.buf.append(value)
            self.sum_of_pow += value ** 2
            if not self.ignore_mean:
                self.mean = (self.mean * n + value) / len(self.buf)

        self.data.addDict({
            self.idx_key: index,
            self.ret_key: math.sqrt(
                self.sum_of_pow / len(self.buf) - self.mean ** 2
            )
        })
    def deal(self, _market_event: MarketEvent):
        """
        recv ticker data from market supply,
        and split into min, the call do_deal(...)

        :param _market_event:
        :return:
        """
        symbol = _market_event.symbol
        data = _market_event.data

        for period in self.min_periods:
            key = symbol + (period, )
            try:
                spliter = self.split_dict[key]
            except KeyError:
                spliter = self.split_dict[key] = SplitIntoMinute(period)

            flag = False
            for d in data:
                flag = flag or spliter.addOne(d)
            if flag:  # gen new bar
                if len(spliter.getBarList()) > 1:  # has finished bar
                    last_bar = spliter.getBarList().pop(0)
                    last_begin_time = spliter.getBarBeginTimeList().pop(0)
                    last_end_time = spliter.getBarEndTimeList().pop(0)
                    price_list = last_bar['price']
                    volume_list = last_bar['amount']
                    bar_data = DataStruct([
                        'open', 'high', 'low', 'close', 'volume', 'begin_time',
                        'end_time'
                    ], 'begin_time')
                    bar_data.addDict({
                        'open': price_list[0],
                        'high': max(price_list),
                        'low': min(price_list),
                        'close': price_list[-1],
                        'volume': sum(volume_list),
                        'begin_time': last_begin_time,
                        'end_time': last_end_time
                    })
                    self.do_deal(
                        MarketEvent(_market_event.market_register_key,
                                    _market_event.strategy,
                                    _market_event.symbol, bar_data), period)
Пример #34
0
    def signalToLongShort(
            self, _backtest_key: str, _strategy: str = None
    ) -> typing.Tuple[DataStruct, DataStruct]:
        signal_list = self.fetchSignalRecords(_backtest_key, _strategy)
        keys = [
            'type', 'symbol', 'strategy', 'signal_type',
            'tradingday', 'datetime', 'strength'
        ]
        long_ret = DataStruct(keys, 'datetime')
        short_ret = DataStruct(keys, 'datetime')

        for d in signal_list:
            if d['signal_type'] == SignalType.LONG:
                long_ret.addDict(d)
            if d['signal_type'] == SignalType.SHORT:
                short_ret.addDict(d)

        return long_ret, short_ret
Пример #35
0
class Volatility(IndicatorAbstract):
    def __init__(
            self, _period: int,
            _factor: int = 1,
            _smooth: int = 1,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'volatility',
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.last_price = None
        self.period = _period
        self.factor = math.sqrt(_factor)
        self.smooth = _smooth
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        price_value = _data_struct[self.use_key][0]
        if self.last_price is not None:
            chg_rate = price_value / self.last_price - 1
            self.buf.append(chg_rate)

            std_value = statistics.pstdev(self.buf) * self.factor
            if self.smooth > 1 and len(self.data):
                last_std_value = self.data[self.ret_key][-1]
                std_value = (
                    (self.smooth - 1) * last_std_value + std_value
                ) / self.smooth

            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: std_value,
            })
        self.last_price = price_value
Пример #36
0
class FastSTD(IndicatorAbstract):
    def __init__(self,
                 _period: int,
                 _ignore_mean: bool = False,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'std'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.sum_of_pow = 0.0
        self.mean = 0.0

        self.period = _period
        self.ignore_mean = _ignore_mean
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        value = _data_struct[self.use_key][0]
        index = _data_struct.index()[0]
        if len(self.buf) >= self.period:
            last_value = self.buf.popleft()
            self.buf.append(value)
            self.sum_of_pow += value**2
            self.sum_of_pow -= last_value**2
            if not self.ignore_mean:
                self.mean += (value - last_value) / self.period
        else:
            n = len(self.buf)
            self.buf.append(value)
            self.sum_of_pow += value**2
            if not self.ignore_mean:
                self.mean = (self.mean * n + value) / len(self.buf)

        self.data.addDict({
            self.idx_key:
            index,
            self.ret_key:
            math.sqrt(self.sum_of_pow / len(self.buf) - self.mean**2)
        })
Пример #37
0
class ReturnRate(IndicatorAbstract):
    def __init__(self,
                 _smooth_period: int = 1,
                 _skip_period: int = 1,
                 _use_abs: bool = False,
                 _use_percent: bool = False,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'returnrate'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.skip_period = _skip_period
        self.smooth_period = _smooth_period
        self.buf = deque(maxlen=self.skip_period)
        self.last_rate = None

        self.use_abs = _use_abs
        self.use_percent = _use_percent

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        if len(self.buf) >= self.skip_period:
            last_value = self.buf.popleft()
            chg_rate = value / last_value - 1
            if self.use_abs:
                chg_rate = abs(chg_rate)
            if self.use_percent:
                chg_rate *= 100.0
            if self.last_rate is None:
                self.last_rate = chg_rate
            else:
                self.last_rate = (chg_rate - self.last_rate) / \
                    self.smooth_period + self.last_rate
            self.data.addDict({
                self.idx_key: index,
                self.ret_key: self.last_rate
            })
        self.buf.append(value)
Пример #38
0
    def fillToBuySell(
            self,
            _backtest_key: str,
            _strategy: str = None) -> typing.Tuple[DataStruct, DataStruct]:
        fill_list = self.fetchFillRecords(_backtest_key, _strategy)
        keys = [
            'type', 'index', 'symbol', 'tradingday', 'datetime', 'quantity',
            'action', 'direction', 'price', 'commission', 'strategy'
        ]
        buy_ret = DataStruct(keys, 'datetime')
        sell_ret = DataStruct(keys, 'datetime')

        for d in fill_list:
            if d['direction'] == DirectionType.BUY:
                buy_ret.addDict(d)
            if d['direction'] == DirectionType.SELL:
                sell_ret.addDict(d)

        return buy_ret, sell_ret
Пример #39
0
    def signalToLongShort(
            self,
            _backtest_key: str,
            _strategy: str = None) -> typing.Tuple[DataStruct, DataStruct]:
        signal_list = self.fetchSignalRecords(_backtest_key, _strategy)
        keys = [
            'type', 'symbol', 'strategy', 'signal_type', 'tradingday',
            'datetime', 'strength'
        ]
        long_ret = DataStruct(keys, 'datetime')
        short_ret = DataStruct(keys, 'datetime')

        for d in signal_list:
            if d['signal_type'] == SignalType.LONG:
                long_ret.addDict(d)
            if d['signal_type'] == SignalType.SHORT:
                short_ret.addDict(d)

        return long_ret, short_ret
Пример #40
0
    def fillToBuySell(
            self, _backtest_key: str, _strategy: str = None
    ) -> typing.Tuple[DataStruct, DataStruct]:
        fill_list = self.fetchFillRecords(_backtest_key, _strategy)
        keys = [
            'type', 'index', 'symbol', 'tradingday',
            'datetime', 'quantity', 'action', 'direction',
            'price', 'commission', 'strategy'
        ]
        buy_ret = DataStruct(keys, 'datetime')
        sell_ret = DataStruct(keys, 'datetime')

        for d in fill_list:
            if d['direction'] == DirectionType.BUY:
                buy_ret.addDict(d)
            if d['direction'] == DirectionType.SELL:
                sell_ret.addDict(d)

        return buy_ret, sell_ret
Пример #41
0
class ATR(IndicatorAbstract):
    def __init__(
            self, _period: int,
            _high_key: str = 'highprice',
            _low_key: str = 'lowprice',
            _close_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'atr'
    ):
        super().__init__()

        self.high_key = _high_key
        self.low_key = _low_key
        self.close_key = _close_key

        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period

        self.last_atr = None
        self.last_close_price = None

    def _addOne(self, _data_struct: DataStruct):
        if self.last_close_price is not None:
            index_value = _data_struct.index()[0]
            tr_value = max(
                _data_struct[self.high_key][0], self.last_close_price
            ) - min(
                _data_struct[self.low_key][0], self.last_close_price
            )
            if self.last_atr is None:
                self.last_atr = tr_value
            else:
                self.last_atr = (tr_value - self.last_atr) / self.period + self.last_atr
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: self.last_atr,
            })
        self.last_close_price = _data_struct[self.close_key][0]
Пример #42
0
class LowBar(BarIndicatorAbstract):
    def __init__(self,
                 _use_key: str,
                 _idx_key: str = 'time',
                 _ret_key: str = 'low'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

    def _addOne(self,
                _data_struct: DataStruct,
                _idx: typing.Union[str, datetime] = None):
        self.data.addDict({
            self.idx_key: _idx,
            self.ret_key: min(_data_struct[self.use_key])
        })
Пример #43
0
class RSI(IndicatorAbstract):
    def __init__(
            self, _period: int, _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'rsi'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.period = _period
        self.gain_buf = deque(maxlen=self.period)
        self.loss_buf = deque(maxlen=self.period)

        self.last_price = None

    def _addOne(self, _data_struct: DataStruct):
        price = _data_struct[self.use_key][0]
        if self.last_price is not None:
            price_diff = price - self.last_price
            if price_diff >= 0:
                self.gain_buf.append(price_diff)
                self.loss_buf.append(0)
            else:
                self.gain_buf.append(0)
                self.loss_buf.append(-price_diff)

            index_value = _data_struct.index()[0]
            gain_mean = statistics.mean(self.gain_buf)
            loss_mean = max(statistics.mean(self.loss_buf), 0.01)
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: 100 - 100 / (1 + gain_mean / loss_mean),
            })

        self.last_price = price
Пример #44
0
class OpenBar(BarIndicatorAbstract):
    def __init__(
            self, _use_key: str, _idx_key: str = 'time', _ret_key: str = 'open'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

    def _addOne(
            self, _data_struct: DataStruct,
            _idx: typing.Union[str, datetime] = None
    ):
        self.data.addDict({
            self.idx_key: _idx,
            self.ret_key: _data_struct[self.use_key][0]
        })
Пример #45
0
class STD(IndicatorAbstract):
    def __init__(self,
                 _period: int,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'std'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.buf = deque(maxlen=self.period)

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        self.buf.append(_data_struct.getColumn(self.use_key)[0])
        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: statistics.pstdev(self.buf),
        })
Пример #46
0
class Kalman(IndicatorAbstract):
    def __init__(
            self, _init_x: float = 0.0, _init_P: float = 1.0,
            _R: float = 0.1 ** 2, _Q: float = 0.01 ** 2,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'kalman'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.x = _init_x
        self.P = _init_P

        self.R = _R
        self.Q = _Q

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]

        self.P += self.Q
        k = self.P / (self.P + self.R)
        self.x += k * (value - self.x)
        self.P = (1 - k) * self.P

        self.data.addDict({
            self.idx_key: index,
            self.ret_key: self.x
        })
Пример #47
0
class FastMA(IndicatorAbstract):
    """
    rolling ma
    """
    def __init__(self,
                 _period: int,
                 _use_key: str = 'closeprice',
                 _idx_key: str = 'time',
                 _ret_key: str = 'ma'):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key)

        self.period = _period
        self.buf = deque(maxlen=self.period)
        self.mean = 0.0

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        value = _data_struct[self.use_key][0]
        if len(self.buf) >= self.period:
            last_value = self.buf.popleft()
            self.buf.append(value)
            self.mean += (value - last_value) / self.period
        else:
            n = len(self.buf)
            self.buf.append(value)
            self.mean = (self.mean * n + value) / len(self.buf)

        self.data.addDict({
            self.idx_key: index,
            self.ret_key: self.mean,
        })
Пример #48
0
class ATRTrailingStop(StopIndicatorAbstract):
    def __init__(
            self,
            _price_data: DataStruct,
            _atr_data: DataStruct,
            _stop_type: int,
            _rate: float = 3,
            _price_use_key: str = 'closeprice',
            _atr_use_key: str = 'atr',
            _idx_key: str = 'time',
            _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_price_data) == 1
        assert len(_atr_data) == 1

        self.stop_type = _stop_type
        self.rate = _rate
        self.price_use_key = _price_use_key
        self.atr_use_key = _atr_use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key,
        )

        self.best_price = _price_data[self.price_use_key][0]
        self._addOne(_price_data, _atr_data)

    def get_stop_price(self, _price, _atr) -> float:
        if self.stop_type == SignalType.LONG:
            self.best_price = max(self.best_price, _price)
            return self.best_price - self.rate * _atr
        elif self.stop_type == SignalType.SHORT:
            self.best_price = min(self.best_price, _price)
            return self.best_price + self.rate * _atr
        else:
            raise Exception('unknown type')

    def addOne(
            self, _data_struct: DataStruct,
            _atr_data: DataStruct = None,
    ) -> bool:
        if not self.is_stop:
            assert len(_data_struct) == 1
            self._addOne(_data_struct, _atr_data)
            self._isStop(_data_struct)

        return self.is_stop

    def _addOne(
            self, _price_data: DataStruct,
            _atr_data: DataStruct = None,
    ):
        assert len(_atr_data) == 1

        price = _price_data.toDict()[self.price_use_key]
        atr = _atr_data.toDict()[self.atr_use_key]

        price_time = _price_data.index()[0]
        atr_time = _atr_data.index()[0]
        assert price_time == atr_time

        self.data.addDict({
            self.idx_key: price_time,
            self.ret_key: self.get_stop_price(price, atr),
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct.toDict()[self.price_use_key]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')
Пример #49
0
class ARMAGARCH(IndicatorAbstract):

    def __init__(
            self,
            _fit_period: int = 60,
            _fit_begin: int = 252,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: typing.Tuple[str] = ('mean', 'std'),
    ):
        super().__init__()

        # fitting control
        self.fit_count = 0
        self.fit_period = _fit_period
        self.fit_begin = _fit_begin

        self.model = ARMAIGARCHModel(_use_mu=False)

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        self.data = DataStruct(
            [self.idx_key, self.ret_key[0], self.ret_key[1]],
            self.idx_key
        )
        # log return buf
        self.last_price = None
        self.return_buf = []
        # model params
        self.phi = None
        self.theta = None
        self.alpha = None
        self.beta = None
        self.const = None
        self.new_mean = None
        self.new_info = None
        self.new_var = None

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        if self.last_price is not None:
            rate = math.log(price) - math.log(self.last_price)
            if self.new_mean is not None:
                self.new_info = rate - self.new_mean
            self.return_buf.append(rate)

            self.fit_count += 1  # retrain model
            if self.fit_count > self.fit_period and \
                    len(self.return_buf) >= self.fit_begin:
                self.model.fit(self.return_buf)
                self.phi = self.model.getPhis()[0]
                self.theta = self.model.getThetas()[0]
                self.alpha = self.model.getAlphas()[0]
                self.beta = self.model.getBetas()[0]
                self.const = self.model.getConst()[0]
                self.new_info = self.model.latent_arma_arr[-1]
                self.new_var = self.model.latent_garch_arr[-1]
                self.fit_count = 0

            if self.new_info is not None:  # predict value
                self.new_mean = self.phi * rate + self.theta * self.new_info
                self.new_var = self.alpha * self.new_info ** 2 + \
                               self.beta * self.new_var + self.const
                self.data.addDict({
                    self.idx_key: index,
                    self.ret_key[0]: self.new_mean,
                    self.ret_key[1]: math.sqrt(self.new_var),
                })

        self.last_price = price
Пример #50
0
class SAR(IndicatorAbstract):
    BEGIN = 0
    RISING = 1
    FALLING = -1

    def __init__(
            self,
            _init_step: float = 0.02,
            _max_step: float = 0.2,
            _close_key: str = 'closeprice',
            _high_key: str = 'highprice',
            _low_key: str = 'lowprice',
            _idx_key: str = 'time',
            _ret_key: str = 'sar',
    ):
        super().__init__()

        self.close_key = _close_key
        self.high_key = _high_key
        self.low_key = _low_key

        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.init_step = _init_step
        self.max_step = _max_step

        self.status = self.BEGIN
        self.ep = None
        self.step = None
        self.sar = None

    def _addOne(self, _data_struct: DataStruct):
        index_value = _data_struct.index()[0]
        close_price = _data_struct[self.close_key][0]
        high_price = _data_struct[self.high_key][0]
        low_price = _data_struct[self.low_key][0]

        if self.status == self.RISING:  # last status if rising
            if low_price < self.sar:  # if break sar, change status
                self.status = self.FALLING
                self.sar = self.ep  # new sar if the ep of last status
                self.ep = low_price
                self.step = self.init_step
            else:  # else continue rising
                self.sar += self.step * (self.ep - self.sar)
                if high_price > self.ep:
                    self.ep = high_price
                    self.step = min(self.max_step, self.step + self.init_step)
        elif self.status == self.FALLING:
            if high_price > self.sar:  # if break sar, change status
                self.status = self.RISING
                self.sar = self.ep
                self.ep = high_price
                self.step = self.init_step
            else:  # else continue falling
                self.sar -= self.step * (self.sar - self.ep)
                if low_price < self.ep:
                    self.ep = low_price
                    self.step = min(self.max_step, self.step + self.init_step)
        else:  # just begin
            if close_price >= (high_price + low_price) / 2:
                # close price greater than mid of high and low
                self.status = self.RISING
                self.ep = high_price
                self.step = self.init_step
                self.sar = low_price
            else:
                self.status = self.FALLING
                self.ep = low_price
                self.step = self.init_step
                self.sar = high_price

        self.data.addDict({
            self.idx_key: index_value,
            self.ret_key: self.sar,
        })
class VolatilityTrailingStop(StopIndicatorAbstract):
    def __init__(
            self,
            _price_data: DataStruct,
            _volatility_data: DataStruct,
            _stop_type: int,
            _rate: float = 4,
            _price_use_key: str = 'closeprice',
            _volatility_use_key: str = 'volatility',
            _idx_key: str = 'time',
            _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_price_data) == 1
        assert len(_volatility_data) == 1

        self.stop_type = _stop_type
        self.rate = _rate
        self.price_use_key = _price_use_key
        self.volatility_use_key = _volatility_use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key,
        )

        self._addOne(_price_data, _volatility_data)

    def get_stop_price(self, _price, _volatility):
        if len(self.data):
            last_stop_price = self.data[self.ret_key][-1]
            if self.stop_type == SignalType.LONG:
                return max(_price * (1 - self.rate * _volatility), last_stop_price)
            elif self.stop_type == SignalType.SHORT:
                return min(_price * (1 + self.rate * _volatility), last_stop_price)
            else:
                raise Exception('unknown type')
        else:
            if self.stop_type == SignalType.LONG:
                return _price * (1 - self.rate * _volatility)
            elif self.stop_type == SignalType.SHORT:
                return _price * (1 + self.rate * _volatility)
            else:
                raise Exception('unknown type')

    def addOne(
            self, _data_struct: DataStruct,
            _volatility_data: DataStruct = None,
    ) -> bool:
        if not self.is_stop:
            assert len(_data_struct) == 1
            self._addOne(_data_struct, _volatility_data)
            self._isStop(_data_struct)

        return self.is_stop

    def _addOne(
            self, _price_data: DataStruct,
            _volatility_data: DataStruct = None,
    ):
        assert len(_volatility_data) == 1

        price = _price_data.toDict()[self.price_use_key]
        volatility = _volatility_data.toDict()[self.volatility_use_key]

        price_time = _price_data.index()[0]
        volatility_time = _volatility_data.index()[0]
        assert price_time == volatility_time

        self.data.addDict({
            self.idx_key: price_time,
            self.ret_key: self.get_stop_price(price, volatility),
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct.toDict()[self.price_use_key]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')
Пример #52
0
class GARCH(IndicatorAbstract):

    def __init__(
            self,
            _fit_period: int = 60,
            _fit_begin: int = 252,
            _factor: int = 1,
            _smooth_period: int = 1,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'predict',
    ):
        super().__init__()

        # fitting control
        self.fit_count = 0
        self.fit_period = _fit_period
        self.fit_begin = _fit_begin
        # scale the volatility
        self.factor = math.sqrt(_factor)
        self.smooth_period = _smooth_period

        self.model = IGARCHModel(_use_mu=False)

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key

        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )
        # log return buf
        self.last_price = None
        self.return_buf = []
        # model params
        self.alpha = None
        self.beta = None
        self.const = None
        self.latent = None

    def _addOne(self, _data_struct: DataStruct):
        index = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        if self.last_price is not None:
            rate = math.log(price) - math.log(self.last_price)
            self.return_buf.append(rate)

            self.fit_count += 1
            if self.fit_count > self.fit_period and \
                    len(self.return_buf) >= self.fit_begin:
                # retrain model and reset sigma2
                self.model.fit(self.return_buf)
                # print(
                #     self.model.getAlphas(), self.model.getBetas(),
                #     self.model.getConst(), self.model.getMu()
                # )
                self.alpha = self.model.getAlphas()[0]
                self.beta = self.model.getBetas()[0]
                self.const = self.model.getConst()[0]
                self.latent = self.model.latent_arr[-1]
                self.fit_count = 0

            if self.latent is not None:  # predict value
                self.latent = self.alpha * rate * rate + \
                    self.beta * self.latent + self.const
                predict = math.sqrt(self.latent)
                predict *= self.factor
                if self.smooth_period > 1 and len(self.data):  # smooth
                    last_value = self.data[self.ret_key][-1]
                    predict = (predict - last_value) / \
                        self.smooth_period + last_value
                self.data.addDict({
                    self.idx_key: index,
                    self.ret_key: predict,
                })

        self.last_price = price
Пример #53
0
class Plunge(IndicatorAbstract):
    def __init__(
            self,
            _fast_ema_period: int = 50,
            _slow_ema_period: int = 100,
            _atr_period: int = 20,
            _extreme_period: int = 20,
            _smooth_period: int = 1,
            _high_key: str = 'highprice',
            _low_key: str = 'lowprice',
            _close_key: str = 'closeprice',
            _idx_key: str = 'time', _ret_key: str = 'plunge'
    ):
        super().__init__()

        self.high_key = _high_key
        self.low_key = _low_key
        self.close_key = _close_key

        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.fast_ema_period = _fast_ema_period
        self.slow_ema_period = _slow_ema_period
        self.fast_ema_value = None
        self.slow_ema_value = None

        self.atr_buf = deque(maxlen=_atr_period)

        self.high_buf = deque(maxlen=_extreme_period)
        self.low_buf = deque(maxlen=_extreme_period)

        self.ret_buf = deque(maxlen=_smooth_period)

        self.last_close_price = None

    def _addOne(self, _data_struct: DataStruct):
        self.high_buf.append(_data_struct[self.high_key][0])
        self.low_buf.append(_data_struct[self.low_key][0])
        closeprice = _data_struct[self.close_key][0]
        if self.last_close_price is not None:
            index_value = _data_struct.index()[0]
            # atr
            tr_value = max(
                _data_struct[self.high_key][0], self.last_close_price
            ) - min(_data_struct[self.low_key][0], self.last_close_price)
            self.atr_buf.append(tr_value)
            atr_value = sum(self.atr_buf) / len(self.atr_buf)
            # ema
            self.fast_ema_value = (closeprice - self.fast_ema_value) / \
                                  self.fast_ema_period + self.fast_ema_value
            self.slow_ema_value = (closeprice - self.slow_ema_value) / \
                                  self.slow_ema_period + self.slow_ema_value
            # plunge
            if self.fast_ema_value > self.slow_ema_value:
                plunge_value = (max(self.high_buf) - closeprice) / atr_value
            elif self.fast_ema_value < self.slow_ema_value:
                plunge_value = (closeprice - min(self.low_buf)) / atr_value
            else:
                plunge_value = 0.0
            self.ret_buf.append(plunge_value)
            self.data.addDict({
                self.idx_key: index_value,
                self.ret_key: sum(self.ret_buf) / len(self.ret_buf),
            })
        else:
            self.fast_ema_value = closeprice
            self.slow_ema_value = closeprice
        self.last_close_price = closeprice
Пример #54
0
class ZigZag(IndicatorAbstract):
    UNKNOWN = 0
    UP = 1
    DOWN = 2

    def __init__(
            self, _threshold: float,
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _ret_key: str = 'zigzag'
    ):
        super().__init__()

        self.use_key = _use_key
        self.idx_key = _idx_key
        self.ret_key = _ret_key
        self.data = DataStruct(
            [self.idx_key, self.ret_key],
            self.idx_key
        )

        self.threshold = _threshold
        self.status = ZigZag.UNKNOWN

        self.high_time: typing.Union[str, datetime] = None
        self.high_price: float = None
        self.low_time: typing.Union[str, datetime] = None
        self.low_price: float = None

    def _addOne(self, _data_struct: DataStruct):
        time: typing.Union[str, datetime] = _data_struct.index()[0]
        price: float = _data_struct[self.use_key][0]

        if self.status == ZigZag.UNKNOWN:
            # update high and low point
            if self.high_price is None or price > self.high_price:
                self.high_time = time
                self.high_price = price
            if self.low_price is None or price < self.low_price:
                self.low_time = time
                self.low_price = price
            # if change status
            if (price - self.low_price) > self.threshold * self.low_price:
                self.status = ZigZag.UP
                self.data.addDict({
                    self.idx_key: self.low_time,
                    self.ret_key: self.low_price,
                })
                # reset high
                self.high_time = time
                self.high_price = price
                # clear low
                self.low_time = None
                self.low_price = None
            if (self.high_price - price) > self.threshold * self.high_price:
                self.status = ZigZag.DOWN
                self.data.addDict({
                    self.idx_key: self.high_time,
                    self.ret_key: self.high_price,
                })
                # reset low
                self.low_time = time
                self.low_price = price
                # clear high
                self.high_time = None
                self.high_price = None
        elif self.status == ZigZag.UP:
            if price > self.high_price:
                self.high_time = time
                self.high_price = price
            if (self.high_price - price) > self.threshold * self.high_price:
                self.status = ZigZag.DOWN
                self.data.addDict({
                    self.idx_key: self.high_time,
                    self.ret_key: self.high_price,
                })
                # reset low
                self.low_time = time
                self.low_price = price
                # clear high
                self.high_time = None
                self.high_price = None
        elif self.status == ZigZag.DOWN:
            if price < self.low_price:
                self.low_time = time
                self.low_price = price
            if (price - self.low_price) > self.threshold * self.low_price:
                self.status = ZigZag.UP
                self.data.addDict({
                    self.idx_key: self.low_time,
                    self.ret_key: self.low_price,
                })
                # reset high
                self.high_time = time
                self.high_price = price
                # clear low
                self.low_time = None
                self.low_price = None
        else:
            raise Exception('unknown status')
Пример #55
0
class StepDrawdownStop(StopIndicatorAbstract):
    def __init__(
            self,
            _data: DataStruct,
            _stop_type: int,
            _init_stop: float = 0.05,
            _profit_thresh: typing.Sequence[float] = (
                    0.1, 0.2, 0.3, 0.5
            ),
            _stop_thresh: typing.Sequence[float] = (
                    1.0, 0.5, 0.3, 0.15
            ),
            _use_key: str = 'closeprice',
            _idx_key: str = 'time',
            _status_key: str = 'status',
            _ret_key: str = 'stopprice',
    ):
        super().__init__()

        assert len(_data) == 1

        self.stop_type = _stop_type
        self.status = 0

        self.profit_thresh = _profit_thresh
        self.stop_thresh = _stop_thresh
        self.use_key = _use_key
        self.idx_key = _idx_key
        self.status_key = _status_key
        self.ret_key = _ret_key

        self.init_price = _data.toDict()[self.use_key]
        if self.stop_type == SignalType.LONG:
            self.init_stop_price = self.init_price * (1 - _init_stop)
        elif self.stop_type == SignalType.SHORT:
            self.init_stop_price = self.init_price * (1 + _init_stop)
        else:
            raise Exception('unknown type')
        self.best_price = self.init_price

        self.data = DataStruct(
            [self.idx_key, self.status_key, self.ret_key],
            self.idx_key,
            [[_data.index()[0], self.status, self.init_stop_price]]
        )

    def _set_best_price(self, _price):
        if self.stop_type == SignalType.LONG:
            self.best_price = max(self.best_price, _price)
        elif self.stop_type == SignalType.SHORT:
            self.best_price = min(self.best_price, _price)
        else:
            raise Exception('unknown type')

    def _profit_rate(self, _price) -> float:
        if self.stop_type == SignalType.LONG:
            return _price / self.init_price - 1.0
        elif self.stop_type == SignalType.SHORT:
            return 1.0 - _price / self.init_price
        else:
            raise Exception('unknown type')

    def _update_status(self, _profit_rate):
        while True:
            if self.status < len(self.profit_thresh):
                if _profit_rate > self.profit_thresh[self.status]:
                    self.status += 1
                else:
                    return
            else:
                return

    def _calc_stop_price(self) -> typing.Union[None, float]:
        if self.status > 0:
            if self.stop_type == SignalType.LONG:
                return self.init_price + \
                       (1.0 - self.stop_thresh[self.status - 1]) * \
                       (self.best_price - self.init_price)
            elif self.stop_type == SignalType.SHORT:
                return self.init_price - \
                       (1.0 - self.stop_thresh[self.status - 1]) * \
                       (self.init_price - self.best_price)
            else:
                raise Exception('unknown type')
        else:
            return self.init_stop_price

    def _addOne(self, _data_struct: DataStruct):
        time = _data_struct.index()[0]
        price = _data_struct[self.use_key][0]

        self._set_best_price(price)

        profit_rate = self._profit_rate(price)
        # if self.stop_type == SignalType.SHORT:
        #     input((profit_rate, self.status))
        self._update_status(profit_rate)

        self.data.addDict({
            self.idx_key: time,
            self.status_key: self.status,
            self.ret_key: self._calc_stop_price(),
        })

    def _isStop(self, _data_struct: DataStruct):
        price = _data_struct.toDict()[self.use_key]
        stop_price = self.data[self.ret_key][-1]
        if self.stop_type == SignalType.LONG:
            if price < stop_price:
                self.is_stop = True
        elif self.stop_type == SignalType.SHORT:
            if price > stop_price:
                self.is_stop = True
        else:
            raise Exception('unknown type')