Example #1
0
if __name__ == '__main__':
    factor_name = 'factor_ma10'
    path = LocalDataPath.path + LocalDataFolderName.FACTOR.value + '/'
    factor_ma5 = get_local_data(path, factor_name + '.h5')
    # 指数数据不全,需要删一部分因子数据
    factor_ma5 = factor_ma5[factor_ma5.index < datetime.datetime(2020, 1, 1)]

    kline_object = GetKlineData()
    market_data = kline_object.cache_all_stock_data(
        dividend_type=RightsAdjustment.BACKWARD.value, field=['close'])
    market_close_data = kline_object.get_market_data(market_data,
                                                     field=['close'])

    # 指数行情,沪深300代替
    all_index_data = kline_object.cache_all_index_data()
    benchmark_df = kline_object.get_market_data(
        all_index_data, stock_code=['000300.SH'],
        field=['close']).to_frame(name='close')
    # 沪深300 的日线,有脏数据,后续单独处理
    if datetime.datetime(2016, 1, 1) in benchmark_df.index:
        benchmark_df = benchmark_df.drop(datetime.datetime(2016, 1, 1))
    regression_analysis_obj = RegressionAnalysis(factor_ma5, 'factor_ma5',
                                                 market_close_data,
                                                 benchmark_df)
    regression_analysis_obj.cal_factor_return('float_value_inverse')
    regression_analysis_obj.cal_t_value_statistics()
    regression_analysis_obj.cal_net_analysis()
    regression_analysis_obj.cal_acf()

    regression_analysis_obj.save_regression_analysis_result(factor_name)
Example #2
0
class StrategyBase(metaclass=ABCMeta):
    def __init__(self, strategy_name='ma_strategy'):
        self._strategy_name = strategy_name
        self._run_mode = RunMode.BACKTESTING.value
        self._account = []
        self._capital = 1000000
        self._start = datetime(2017, 1, 1)
        self._end = datetime(2018, 1, 1)
        self._benchmark = '000300.SH'
        self._period = Period.DAILY.value  # 后续支持1min 3min 5min 等多周期
        self._universe = []
        self._rights_adjustment = RightsAdjustment.FROWARD.value
        self._time_tag = 0
        # 数据缓存开关
        self._daily_data_cache = False
        self._one_min_data_cache = False
        # 取数据
        self._get_data = GetKlineData()
        self.bar_index = 0

    @property
    def strategy_name(self):
        return self._strategy_name

    @strategy_name.setter
    def strategy_name(self, value):
        self._strategy_name = value

    @property
    def run_mode(self):
        return self._run_mode

    @run_mode.setter
    def run_mode(self, value):
        self._run_mode = value

    @property
    def account(self):
        return self._account

    @account.setter
    def account(self, value):
        self._account = value

    @property
    def capital(self):
        return self._capital

    @capital.setter
    def capital(self, value):
        self._capital = value

    @property
    def start(self):
        return self._start

    @start.setter
    def start(self, value):
        self._start = value

    @property
    def end(self):
        return self._end

    @end.setter
    def end(self, value):
        self._end = value

    @property
    def benchmark(self):
        return self._benchmark

    @benchmark.setter
    def benchmark(self, value):
        self._benchmark = value

    @property
    def period(self):
        return self._period

    @period.setter
    def period(self, value):
        self._period = value

    @property
    def universe(self):
        return self._universe

    @universe.setter
    def universe(self, value):
        self._universe.extend(value)

    @property
    def rights_adjustment(self):
        return self._rights_adjustment

    @rights_adjustment.setter
    def rights_adjustment(self, value):
        self._rights_adjustment = value

    @property
    def time_tag(self):
        return self._time_tag

    @time_tag.setter
    def time_tag(self, value):
        self._time_tag = value

    @property
    def daily_data_cache(self):
        return self._daily_data_cache

    @daily_data_cache.setter
    def daily_data_cache(self, value):
        self._daily_data_cache = value

    @property
    def one_min_data_cache(self):
        return self._one_min_data_cache

    @one_min_data_cache.setter
    def one_min_data_cache(self, value):
        self._one_min_data_cache = value

    # 回测滑点设置
    def set_slippage(self,
                     stock_type=StockType.STOCK.value,
                     slippage_type=SlippageType.SLIPPAGE_FIX.value,
                     value=0):
        Environment.slippage_dict[stock_type] = {
            'slippage_type': slippage_type,
            'value': value
        }

    # 回测手续费和印花税
    def set_commission(self,
                       stock_type=StockType.STOCK.value,
                       tax=0,
                       open_commission=0,
                       close_commission=0,
                       close_today_commission=0,
                       min_commission=0):
        Environment.commission_dict[stock_type] = {
            'tax': tax,
            'open_commission': open_commission,
            'close_commission': close_commission,
            'close_today_commission': close_today_commission,
            'min_commission': min_commission
        }

    def run(self, save_trade_record=False):
        self.initialize()
        # 初始化 account_data
        if self.account:
            for account in self.account:
                Environment.current_account_data = AccountData()
                Environment.current_account_data.account_id = generate_random_id.generate_random_id(
                    account)
                Environment.current_account_data.total_balance = self.capital[
                    account]
                Environment.current_account_data.available = self.capital[
                    account]
                # Environment.logger(Environment.current_account_data.account_id, Environment.current_account_data.available)
                Environment.bar_account_data_list.append(
                    Environment.current_account_data)
        # if self.run_mode == RunMode.TRADE.value:
        #     self.end = self._get_data.get_end_time_tag(benchmark=self.benchmark, period=Period.DAILY.value)

        # 缓存数据开关,和bar_index的计算
        if self.period == Period.DAILY.value:
            self.daily_data_cache = True
        elif self.period == Period.ONE_MIN.value:
            self.one_min_data_cache = True
        #
        security_list = copy.copy(self.universe)
        security_list = list(set(security_list))
        if self._daily_data_cache:
            Environment.daily_data = self._get_data.cache_all_stock_data(
                dividend_type=self.rights_adjustment)
            Environment.index_daily_data = self._get_data.cache_all_index_data(
            )

        if self.one_min_data_cache:
            Environment.one_min_data = self._get_data.cache_all_stock_data(
                period=Period.ONE_MIN.value)

        if self.period == Period.DAILY.value:
            Environment.benchmark_index = [
                i for i in Environment.index_daily_data['close'][
                    self.benchmark].index if self.start <= i <= self.end
            ]

        elif self.period == Period.ONE_MIN.value:
            Environment.benchmark_index = [
                data_transfer.date_to_millisecond(str(int(i)), '%Y%m%d') for i
                in Environment.one_min_data['open'].ix[self.benchmark].index
                if i >= data_transfer.date_str_to_int(self.start)
            ]

        self.bar_index = 0

        while True:
            try:
                # Environment.logger(self.time_tag, Environment.benchmark_index)
                self.time_tag = Environment.benchmark_index[self.bar_index]
            except IndexError:
                if self.run_mode == RunMode.BACKTESTING.value:
                    if save_trade_record:
                        run_backtesting_analysis_engine(self)
                        break
                # elif self.run_mode == RunMode.TRADE.value:
                #     读取最新tick, 更新最新的分钟或者日线
                #     if 读取最新tick, 更新最新的分钟或者日线 == done:
                #         daily_data.append(new_day_data)
                #         self.bar_index += 1
                #         benchmark_index.append(new_day_time_tag)
            else:
                run_bar_engine(self)

    @abstractmethod
    def initialize(self):
        """
        设置运行模式,回测、实盘
        设置on_bar运行周期,分钟线、日线
        设置缓存历史数据范围、实时行情订阅
        设置回测的各种设置。手续费、滑点、回测区间等
        :return:
        """
        pass

    def on_bar(self, event):
        """
        支持分钟线、日线的处理
        :param event:
        :return:
        """
        Environment.logger('abstractmethod handle_bar')
        pass

    def on_quote(self, event):
        """
        level1行情数据的推送会自动触发该方法的调用,每只股票数据推送都调用
        :param event:
        :return:
        """
        pass

    def on_transaction(self, event):
        """
        逐笔成交行情数据的推送会自动触发该方法的调用,每只股票数据推送都调用
        :param event:
        :return:
        """
        pass

    def on_entrust(self, event):
        """
        逐笔委托行情数据的推送会自动触发该方法的调用,每只股票数据推送都调用
        :param event:
        :return:
        """
        pass

    def on_order(self, event):
        """
        策略订单成交信息的更新会自动触发该方法的调用。
        :param event:
        :return:
        """
        pass

    def on_cancel_order(self, event):
        """
        策略订单撤单信息的更新会自动触发该方法的调用。
        :param event:
        :return:
        """
        pass

    def on_trade(self, event):
        """
        策略订单委托信息的更新会自动触发该方法的调用。
        :param event:
        :return:
        """
        pass

    def on_account(self, event):
        """
        策略账户信息的更新会自动触发该方法的调用。支持多账户,股票,期货
        :param event:
        :return:
        """
        pass