예제 #1
0
class BollBacktesting(BaseBackTesing):
    def __init__(self):
        super().__init__()
        self.stock_code = None
        self.offline_stock_action = OfflineStockAction()
        self.indicator_strategy = IndicatorStrategy()
        self.boll = None
        self.stock = None
        self.buy_date = None

    def set_stock_code(self, stock_code):
        self.stock_code = stock_code

    def is_buy_position(self, history_prices, current_price):
        all_prices = history_prices
        avg_vol = all_prices.tail(5)['volume'].mean()  # 5日均量
        newest_price = all_prices.tail(1)
        close_price = newest_price['close']
        newest_vol = newest_price['volume']
        newest_high = newest_price['high']
        newest_low = newest_price['low']
        newest_open = newest_price['open']

        last_high_price = all_prices.tail(2).head(1)['high']
        last_close_price = all_prices.tail(2).head(1)['close']
        try:
            if newest_high.item() > last_high_price.item() * 1.03 \
                    and (close_price.item() - newest_open.item()) > 0.8 * (newest_high.item() - newest_low.item()) \
                    and (newest_vol.item() > avg_vol.item()):
                upperband = self.boll['upperband']
                middleband = self.boll['middleband']
                lowerband = self.boll['lowerband']
                if close_price.item() > middleband[len(middleband) - 1] \
                        and last_close_price.item() < middleband[len(middleband) - 2]:
                    log.info("stock_info: %s(%s) close_price:%.2f, +%.2f%%",
                             self.stock['display_name'],
                             self.stock['stock_code'], close_price.item(),
                             (close_price.item() - last_close_price.item()) /
                             last_close_price.item() * 100)
                    log.info("upper :%.2f; middle: %.2f; lower: %.2f",
                             upperband[len(upperband) - 1],
                             middleband[len(middleband) - 1],
                             lowerband[len(lowerband) - 1])
                    log.info(
                        "======================================================"
                    )
                    self.buy_date = datetime.datetime.strptime(
                        str(current_price['trade_day']).split(" ")[0],
                        '%Y-%m-%d')
                    return True
        except ValueError:
            print(newest_high)
            return False
        return False

    def buy_action(self, history_prices, current_price):
        self.buy_position_percent_value(current_price, 1)

    def is_sell_position(self, history_prices, current_price):
        if self.buy_date is not None \
                and self.position > 0:
            cur_date = datetime.datetime.strptime(
                str(current_price['trade_day']).split(" ")[0], '%Y-%m-%d')
            print((cur_date - self.buy_date).days)
            if (cur_date - self.buy_date).days > 3:
                self.buy_date = None
                log.info("持有超过2天,卖出")
                return True
        return False

    def sell_action(self, history_prices, current_price):
        self.sell_position_percent_value(current_price, 1)

    def is_add_position(self, history_prices, current_price):
        super().is_add_position(history_prices, current_price)

    def add_position_action(self, history_prices, current_price):
        super().add_position_action(history_prices, current_price)

    def is_reduce_position(self, history_prices, current_price):
        super().is_reduce_position(history_prices, current_price)

    def reduce_position_action(self, history_prices, current_price):
        super().reduce_position_action(history_prices, current_price)

    def is_clear_position(self, history_prices, current_price):
        if self.position > 0:
            profit = self.position * current_price['open'] - self.INIT_BALANCE
            print(profit)
            if profit < 0 and (-profit) / self.INIT_BALANCE > 0.08:
                log.info("触及止损,清仓")
                return True
        return False

    def clear_position_action(self, history_prices, current_price):
        super().sell_position_percent_value(current_price=current_price,
                                            percent=1)

    def buy_fee(self):
        return super().buy_fee()

    def sell_fee(self):
        return super().sell_fee()

    def end_backtesting(self, history_prices, current_price):
        if self.position > 0:
            self.sell_position_percent_value(current_price, 1)

    def buy_position_percent_value(self, current_price, percent):
        # 早盘就卖
        current_price['close'] = current_price['open']
        return super().buy_position_percent_value(current_price, percent)

    def sell_position_percent_value(self, current_price, percent):
        return super().sell_position_percent_value(current_price, percent)

    def run(self):
        if self.stock_code is None:
            raise Exception("stock code can not be None")
        self.stock = pd.DataFrame(
            self.offline_stock_action.query_by_stock_code(self.stock_code))
        total_history_prices = self.offline_stock_action.query_all_history_prices(
            self.stock_code)
        upperband, middleband, lowerband = self.indicator_strategy.calculate_boll(
            total_history_prices['close'])

        bollinger = {
            'upperband': upperband,
            'middleband': middleband,
            'lowerband': lowerband,
            'trade_day': total_history_prices['trade_day']
        }

        self.boll = pd.DataFrame(bollinger)
        super().run_backtesting(total_history_prices=total_history_prices,
                                start_date=datetime.datetime(2018, 1, 1))
        return float(
            round((self.balance - self.INIT_BALANCE) / self.INIT_BALANCE * 100,
                  2))
예제 #2
0
class SimpleBackTesting(BaseBackTesing):

    def __init__(self):
        BaseBackTesing.__init__(self)
        self.stock_code = None
        self.offline_stock_action = OfflineStockAction()
        self.bull_up_strategy = BullUpStrategy()
        self.indicator_strategy = IndicatorStrategy()
        self.total_dmi = None
        self.stock = None
        self.pressure_level = self.MAX_VALUE
        self.stop_loss_level = 0
        pass

    def set_stock_code(self, stock_code):
        self.stock_code = stock_code

    def is_buy_position(self, history_prices, current_price):
        history_prices = history_prices.append(current_price)
        # 判断是否是反弹时间点
        bull_up_list = self.bull_up_strategy\
            .list_bull_up_stock(count=4, up_thread_hold=0.03,
                                stock_list=self.stock,
                                end_day=current_price['trade_day'],
                                prices=history_prices[history_prices['trade_day']
                                                      <= current_price['trade_day']],
                                safe_flag=True)

        if bull_up_list[0].empty is False:
            self.stock = bull_up_list[0]
            self.pressure_level = self.stock['pressure_price']
            self.stop_loss_level = self.stock['stop_loss_price']
            current_dmi = self.total_dmi[self.total_dmi['trade_day'] == current_price['trade_day']]
            if float(current_dmi['pdi'].tail(1)) > float(current_dmi['mdi'].tail(1)) \
                    and float(current_dmi['adx'].tail(1)) > 30:
                return True
        return False

    def buy_action(self, history_prices, current_price):
        self.buy_position_percent_value(current_price=current_price,
                                        percent=0.8)

    def is_sell_position(self, history_prices, current_price):
        return super().is_sell_position(history_prices, current_price)

    def sell_action(self, history_prices, current_price):
        super().sell_action(history_prices, current_price)

    def is_add_position(self, history_prices, current_price):
        if float(current_price['close']) > float(self.pressure_level) \
                and current_price['volume'] > history_prices.tail(5)['volume'].mean():
            return True
        return super().is_add_position(history_prices, current_price)

    #放量突破压力位,加仓20%
    def add_position_action(self, history_prices, current_price):
        self.stop_loss_level = self.pressure_level
        self.pressure_level = self.pressure_level * 1.05
        self.buy_position_percent_value(current_price=current_price,
                                        percent=0.6)

    def is_reduce_position(self, history_prices, current_price):
        if int(self.position) > 0 and float(current_price['close']) < float(self.pressure_level)\
                < float(current_price['high']):
            return True
        return super().is_reduce_position(history_prices, current_price)

    #遇到压力位如果当天最高价超过,但是收盘没有超过则减仓50%
    def reduce_position_action(self, history_prices, current_price):
        self.sell_position_percent_value(current_price=current_price, percent=0.5)

    def is_clear_position(self, history_prices, current_price):
        if int(self.position) > 0 and float(current_price['close']) < float(self.stop_loss_level):
            return True
        return super().is_clear_position(history_prices, current_price)

    # 到达止损位,清仓出局
    def clear_position_action(self, history_prices, current_price):
        self.sell_position_percent_value(current_price=current_price,
                                         percent=1)

    def buy_fee(self):
        return 5 #TODO 暂时固定按5元

    def sell_fee(self):
        return 5 #TODO 暂时固定按5元

    def end_backtesting(self, history_prices, current_price):
        if self.position > 0:
            self.sell_position_percent_value(current_price=current_price,
                                             percent=1)

    def run(self):
        if self.stock_code is None:
            raise Exception("stock code can not be None")

        self.stock = pd.DataFrame(self.offline_stock_action.query_by_stock_code(self.stock_code))
        total_history_prices = self.offline_stock_action.query_all_history_prices(
            self.stock_code)
        mdi, pdi, adx = self.indicator_strategy.calculate_dmi(total_history_prices['high'],
                                                              total_history_prices['low'],
                                                              total_history_prices['close'])
        dmis = {
            'mdi': mdi,
            'pdi': pdi,
            'adx': adx,
            'trade_day': total_history_prices['trade_day']
        }
        self.total_dmi = pd.DataFrame(dmis)
        super().run_backtesting(total_history_prices=total_history_prices,
                                start_date=datetime.datetime(2019, 1, 1))

        return float(round((self.balance - self.INIT_BALANCE)/self.INIT_BALANCE*100, 2))
예제 #3
0
class CCIBacktesing(BaseBackTesing):
    def __init__(self):
        BaseBackTesing.__init__(self)
        self.stock_code = None
        self.offline_stock_action = OfflineStockAction()
        self.indicator_strategy = IndicatorStrategy()
        self.cci = None
        self.stock = None

    def set_stock_code(self, stock_code):
        self.stock_code = stock_code

    def is_buy_position(self, history_prices, current_price):
        pre_price = history_prices.tail(1)
        pre_price = pre_price.reset_index(drop=True)
        try:
            pre_cci = self.cci[self.cci['trade_day'] == pre_price['trade_day']
                               [0]]
        except IndexError:
            print(pre_price['trade_day'][0])
            raise Exception("ERROR")
        cur_cci = self.cci[self.cci['trade_day'] == current_price['trade_day']]
        if float(pre_cci['cci']) < 100 < float(cur_cci['cci']):
            return True
        return False

    def buy_action(self, history_prices, current_price):
        cur_cci = self.cci[self.cci['trade_day'] == current_price['trade_day']]

        self.buy_position_percent_value(
            current_price=current_price,
            percent=round(float(cur_cci['cci']) / 100, 1) - 0.5)

    def is_sell_position(self, history_prices, current_price):
        pre_price = history_prices.tail(1)
        pre_price = pre_price.reset_index(drop=True)
        pre_cci = self.cci[self.cci['trade_day'] == pre_price['trade_day'][0]]
        cur_cci = self.cci[self.cci['trade_day'] == current_price['trade_day']]
        if float(pre_cci['cci']) > 100 > float(cur_cci['cci']):
            return True
        return False

    def sell_action(self, history_prices, current_price):
        if self.position > 0:
            self.sell_position_percent_value(current_price=current_price,
                                             percent=1)

    def is_add_position(self, history_prices, current_price):
        super().is_add_position(history_prices=history_prices,
                                current_price=current_price)

    def add_position_action(self, history_prices, current_price):
        super().add_position_action(history_prices=history_prices,
                                    current_price=current_price)

    def is_reduce_position(self, history_prices, current_price):
        super().is_reduce_position(history_prices=history_prices,
                                   current_price=current_price)

    def reduce_position_action(self, history_prices, current_price):
        super().reduce_position_action(history_prices=history_prices,
                                       current_price=current_price)

    def is_clear_position(self, history_prices, current_price):
        if self.position > 0:
            profit = self.balance - self.INIT_BALANCE
            if profit < 0 and (-profit) / self.INIT_BALANCE > 0.08:
                return True
        return False

    def clear_position_action(self, history_prices, current_price):
        super().sell_position_percent_value(current_price=current_price,
                                            percent=1)

    def buy_fee(self):
        return 5

    def sell_fee(self):
        return 5

    def end_backtesting(self, history_prices, current_price):
        if self.position > 0:
            self.sell_position_percent_value(current_price=current_price,
                                             percent=1)

    def buy_position_percent_value(self, current_price, percent):
        super().buy_position_percent_value(current_price, percent)

    def sell_position_percent_value(self, current_price, percent):
        super().sell_position_percent_value(current_price, percent)

    def run(self):
        if self.stock_code is None:
            raise Exception("stock code can not be None")
        self.stock = pd.DataFrame(
            self.offline_stock_action.query_by_stock_code(self.stock_code))
        total_history_prices = self.offline_stock_action.query_all_history_prices(
            self.stock_code)
        ccis = self.indicator_strategy.calculate_cci(
            total_history_prices['high'], total_history_prices['low'],
            total_history_prices['close'])
        cci = {'cci': ccis, 'trade_day': total_history_prices['trade_day']}

        self.cci = pd.DataFrame(cci)
        super().run_backtesting(total_history_prices=total_history_prices,
                                start_date=datetime.datetime(2018, 1, 1))
        return float(
            round((self.balance - self.INIT_BALANCE) / self.INIT_BALANCE * 100,
                  2))