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 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 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 )
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 )
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)
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)
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 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 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)
class OHLC(BarIndicatorAbstract): def __init__( self, _use_key: str, _idx_key: str = 'time', _ret_key: typing.Sequence[str] = ('open', 'high', 'low', 'close') ): super().__init__() self.use_key = _use_key self.idx_key = _idx_key self.ret_key = _ret_key self.data = DataStruct( [self.idx_key] + list(self.ret_key), self.idx_key ) def _addOne( self, _data_struct: DataStruct, _idx: typing.Union[str, datetime] = None ): tmp = _data_struct[self.use_key] self.data.addRow( (_idx, tmp[0], max(tmp), min(tmp), tmp[-1]), [self.idx_key] + list(self.ret_key) )