def __init__(self, _period: int, _use_key: str, _init_n: int = 20, _min_n: int = 20, _max_n: int = 60, _rate: float = 2.0, _idx_key: str = 'time'): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key, 'upband', 'midband', 'downband'] self.data = DataStruct(self.keys, self.idx_key) self.period = _period self.rate = _rate self.buf = [] self.prev_std = None self.dynamic_n = float(_init_n) self.min_n = _min_n self.max_n = _max_n
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 _addOne(self, _data_struct: DataStruct): index_value = _data_struct.index()[0] self.buf.append(_data_struct.getColumn(self.use_key)[0]) if len(self.data) > self.period: const_std = statistics.pstdev(self.buf[-self.period:]) self.dynamic_n *= const_std / self.prev_std self.dynamic_n = max(self.min_n, self.dynamic_n) self.dynamic_n = min(self.max_n, self.dynamic_n) tmp_n = int(round(self.dynamic_n)) mean = statistics.mean(self.buf[-tmp_n:]) std = statistics.pstdev(self.buf[-tmp_n:]) self.data.addRow([ index_value, mean + self.rate * std, mean, mean - self.rate * std ], self.keys) self.prev_std = const_std else: if len(self.data) == self.period: self.prev_std = statistics.pstdev(self.buf) self.data.addRow([index_value, None, None, None], self.keys)
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
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, })
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)
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 __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 self.best_price = _data.toDict()[self.use_key] time = _data.index()[0] self.data = DataStruct([self.idx_key, self.ret_key], self.idx_key, [[time, self.get_stop_price()]])
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.data) > self.period: const_std = statistics.pstdev(self.buf[-self.period:]) self.dynamic_n *= const_std / self.prev_std self.dynamic_n = max(self.min_n, self.dynamic_n) self.dynamic_n = min(self.max_n, self.dynamic_n) tmp_n = int(round(self.dynamic_n)) mean = statistics.mean(self.buf[-tmp_n:]) std = statistics.pstdev(self.buf[-tmp_n:]) self.data.addRow( [index_value, mean + self.rate * std, mean, mean - self.rate * std], self.keys ) self.prev_std = const_std else: if len(self.data) == self.period: self.prev_std = statistics.pstdev(self.buf) self.data.addRow( [index_value, None, None, None], self.keys )
def getSettlementData(self): tmp = DataStruct(['tradingday', 'fund', 'commission', 'margin'], 'tradingday') for d in self.settlement_record: tmp.addDict(d) return tmp
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, })
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
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)
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
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: min(self.buf), })
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)
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]] )
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, })
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')
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), })
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]])
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), })
class BBands(IndicatorAbstract): def __init__( self, _period: int = 26, _use_key: str = 'closeprice', _rate: float = 2.0, _idx_key: str = 'time', _ret_key=('upband', 'midband', 'downband') ): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key] + list(_ret_key) self.data = DataStruct( self.keys, self.idx_key ) self.period = _period self.rate = _rate 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]) mean = statistics.mean(self.buf) std = statistics.pstdev(self.buf, mu=mean) self.data.addRow([ index_value, mean + self.rate * std, mean, mean - self.rate * std ], self.keys)
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
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 self.best_price = _data.toDict()[self.use_key] time = _data.index()[0] self.data = DataStruct( [self.idx_key, self.ret_key], self.idx_key, [[time, self.get_stop_price()]] )
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, })
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: typing.Tuple[str] = ('estimate', 'predict')): super().__init__() self.fit_count = 0 self.fit_period = _fit_period self.fit_begin = _fit_begin self.factor = math.sqrt(_factor) self.smooth_period = _smooth_period 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) self.last_price = None self.rate_buf = [] self.param = None self.sigma2 = None
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, })
class BBands(IndicatorAbstract): def __init__(self, _period: int = 26, _use_key: str = 'closeprice', _rate: float = 2.0, _idx_key: str = 'time', _ret_key=('upband', 'midband', 'downband')): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key] + list(_ret_key) self.data = DataStruct(self.keys, self.idx_key) self.period = _period self.rate = _rate 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]) mean = statistics.mean(self.buf) std = statistics.pstdev(self.buf, mu=mean) self.data.addRow([ index_value, mean + self.rate * std, mean, mean - self.rate * std ], self.keys)
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
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
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, })
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
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), })
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
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
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
def _addOne(self, _data_struct: DataStruct): index_value = _data_struct.index()[0] self.buf.append(_data_struct.getColumn(self.use_key)[0]) mean = statistics.mean(self.buf) std = statistics.pstdev(self.buf, mu=mean) self.data.addRow([ index_value, mean + self.rate * std, mean, mean - self.rate * std ], self.keys)
def getSignalData(self): tmp = DataStruct( ['strategy', 'tradingday', 'datetime', 'symbol', 'strength'], 'datetime') for d in self.signal_record: tmp.addDict(d) return tmp
def _addOne(self, _data_struct: DataStruct): index_value = _data_struct.index()[0] self.buf.append(_data_struct.getColumn(self.use_key)[0]) mean = statistics.mean(self.buf) std = statistics.pstdev(self.buf, mu=mean) self.data.addRow([ index_value, mean + self.rate * std, mean, mean - self.rate * std ], self.keys)
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
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)
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')
class AdaBBands(IndicatorAbstract): def __init__( self, _period: int, _use_key: str, _init_n: int = 20, _min_n: int = 20, _max_n: int = 60, _rate: float = 2.0, _idx_key: str = 'time' ): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key, 'upband', 'midband', 'downband'] self.data = DataStruct( self.keys, self.idx_key ) self.period = _period self.rate = _rate self.buf = [] self.prev_std = None self.dynamic_n = float(_init_n) self.min_n = _min_n self.max_n = _max_n 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.data) > self.period: const_std = statistics.pstdev(self.buf[-self.period:]) self.dynamic_n *= const_std / self.prev_std self.dynamic_n = max(self.min_n, self.dynamic_n) self.dynamic_n = min(self.max_n, self.dynamic_n) tmp_n = int(round(self.dynamic_n)) mean = statistics.mean(self.buf[-tmp_n:]) std = statistics.pstdev(self.buf[-tmp_n:]) self.data.addRow( [index_value, mean + self.rate * std, mean, mean - self.rate * std], self.keys ) self.prev_std = const_std else: if len(self.data) == self.period: self.prev_std = statistics.pstdev(self.buf) self.data.addRow( [index_value, None, None, None], self.keys )
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
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
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, })
class KDJ(IndicatorAbstract): def __init__( self, _k_period: int = 20, _d_period: int = 3, _j_period: int = 3, _close_key: str = 'closeprice', _high_key: str = 'highprice', _low_key: str = 'lowprice', _idx_key: str = 'time', _ret_key=('k', 'd', 'j') ): super().__init__() self.k_period = _k_period self.d_period = _d_period self.j_period = _j_period self.close_key = _close_key self.high_key = _high_key self.low_key = _low_key self.idx_key = _idx_key self.keys = [self.idx_key] + list(_ret_key) self.high_buf = deque(maxlen=self.k_period) self.low_buf = deque(maxlen=self.k_period) self.k_buf = deque(maxlen=self.d_period) self.data = DataStruct( self.keys, self.idx_key ) def _addOne(self, _data: DataStruct): index_value = _data.index()[0] closeprice = _data[self.close_key][0] highprice = _data[self.high_key][0] lowprice = _data[self.low_key][0] self.high_buf.append(highprice) self.low_buf.append(lowprice) high_mean = statistics.mean(self.high_buf) low_mean = statistics.mean(self.low_buf) k = 100 * (closeprice - high_mean) / (high_mean - low_mean) self.k_buf.append(k) d = statistics.mean(self.k_buf) j = self.j_period * k - (self.j_period - 1) * d self.data.addRow( [index_value, k, d, j], self.keys )
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, })
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 })
def _addOne(self, _data_struct: DataStruct): price = _data_struct.toDict()[self.use_key] if self.stop_type == SignalType.LONG: self.best_price = max(price, self.best_price) elif self.stop_type == SignalType.SHORT: self.best_price = min(price, self.best_price) else: raise Exception('unknown type') time = _data_struct.index()[0] self.data.addDict({ self.idx_key: time, self.ret_key: self.get_stop_price(), })
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) ), })
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
class MACD(IndicatorAbstract): def __init__( self, _fast_period: int = 12, _slow_period: int = 26, _macd_period: int = 9, _use_key: str = 'closeprice', _idx_key: str = 'time', _ret_key=('value', 'avg', 'diff') ): super().__init__() self.fast_period = _fast_period self.slow_period = _slow_period self.macd_period = _macd_period self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key] + list(_ret_key) self.fast_value = None self.slow_value = None self.macd_avg = None self.data = DataStruct( self.keys, self.idx_key ) def _addOne(self, _data: DataStruct): index_value = _data.index()[0] price = _data[self.use_key][0] if self.fast_value is None and self.slow_value is None \ and self.macd_avg is None: self.fast_value = price self.slow_value = price macd_value = self.fast_value - self.slow_value self.macd_avg = macd_value else: self.fast_value = (price - self.fast_value) / self.fast_period + self.fast_value self.slow_value = (price - self.slow_value) / self.slow_period + self.slow_value macd_value = self.fast_value - self.slow_value self.macd_avg = (macd_value - self.macd_avg) / self.macd_period + self.macd_avg macd_diff = macd_value - self.macd_avg self.data.addRow( [index_value, macd_value, self.macd_avg, macd_diff], self.keys )
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)
class FastBBands(IndicatorAbstract): def __init__( self, _period: int = 26, _rate: float = 2.0, _ignore_mean: bool = False, _use_key: str = 'closeprice', _idx_key: str = 'time', _ret_key=('upband', 'midband', 'downband') ): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.keys = [self.idx_key] + list(_ret_key) self.data = DataStruct( self.keys, self.idx_key ) self.period = _period self.rate = _rate self.ignore_mean = _ignore_mean self.buf = deque(maxlen=self.period) self.mean = 0.0 self.sum_of_pow = 0.0 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) std = math.sqrt( self.sum_of_pow / len(self.buf) - self.mean ** 2 ) self.data.addRow([ index, self.mean + self.rate * std, self.mean, self.mean - self.rate * std ], self.keys)
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
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