Esempio n. 1
0
    def is_stop(self, code, date):
        """
        判断是否需要止盈,盈利超过指定值,则止盈
        :param code: 股票代码
        :param date: 日期
        :return: True - 止盈,False - 不止盈
        """
        holding_stock = self.account.get_holding(code)
        print('止盈判断:%s' % code, flush=True)
        print(holding_stock, flush=True)
        dm = DataModule()
        if holding_stock is not None:
            df_daily = dm.get_k_data(code,
                                     autype=None,
                                     begin_date=date,
                                     end_date=date)
            if df_daily.index.size > 0:
                df_daily.set_index(['date'], 1, inplace=True)

                profit = (holding_stock['volume'] * df_daily.loc[date]['close'] - holding_stock['cost']) \
                         * 100 / holding_stock['cost']

                return profit >= self.max_profit

        return False
Esempio n. 2
0
def train_model(user_image: Image, style_image: Image):
    """Trains a Deep Learning model to extract the stylings
    from `style_image` and applies them onto `user_image`
    then returns `user_image`.

    Args:
        user_image (Image): Image you want to apply styles onto.
        style_image (Image): Image you want to extract styles from.

    Returns:
        user_image (Image): `user_image` with styling applied.

    """

    image_processor = ImageProcessor(maximum_image_size=(512, 512))
    print(f"user_image.size: {user_image.size} | style_image.size: {style_image.size}")

    image_size = image_processor.get_common_image_size(user_image, style_image)
    # device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    device = "cpu"

    user_image = image_processor.prepare_images(user_image, image_size)
    style_image = image_processor.prepare_images(style_image, image_size)
    normalization_mean = torch.tensor([0.485, 0.456, 0.406]).to(image_processor.device)
    normalization_std = torch.tensor([0.229, 0.224, 0.225]).to(image_processor.device)

    datamodule = DataModule(user_image, style_image)
    model = StyleTransferModel(
        user_image=user_image,
        style_image=style_image,
        normalization_mean=normalization_mean,
        normalization_std=normalization_std,
    )

    cnn = models.vgg19(pretrained=True).features.to(device).eval()

    model._build_model_and_loss_functions(base_cnn_model=cnn)

    print("Training...")
    tb_logger = pl_loggers.TensorBoardLogger("logs/")
    trainer_params = {"max_epochs": 6000}

    if device != "cpu":
        print("Using a gpu!")
        trainer_params["gpus"] = 1

    trainer = pl.Trainer(**trainer_params)
    trainer.fit(model, datamodule)

    sample = user_image.to(device)
    model.to(device)

    image = model(sample)
    image = image_processor.save_image(
        image, "output.png", "Sample Output", display_image=True
    )
    return image
Esempio n. 3
0
    def compute(self, begin_date, end_date):
        """
        计算指定时间段内所有股票的该因子的值,并保存到数据库中
        :param begin_date:  开始时间
        :param end_date: 结束时间
        """
        dm = DataModule()
        frc = FinanceReportCrawler()

        code_report_dict = frc.get_code_reports()

        codes = set(code_report_dict.keys())
        for code in codes:
            dailies = dm.get_k_data(code, autype=None, begin_date=begin_date, end_date=end_date)
            # 如果没有合适的数据
            if dailies.index.size == 0:
                continue

            # 业绩报告列表
            reports = code_report_dict[code]

            dailies.set_index(['date'], inplace=True)

            update_requests = []
            for current_date in dailies.index:
                # 用来保存最后一个公告日期小于等于当前日期的财报
                last_report = None
                for report in reports:
                    announced_date = report['announced_date']
                    # 如果公告日期大于当前调整日,则结束循环
                    if announced_date > current_date:
                        break

                    last_report = report

                # 如果找到了正确时间范围的年报, 则计算PE
                if last_report is not None:
                    pe = dailies.loc[current_date]['close'] / last_report['eps']
                    pe = round(pe, 3)

                    print('%s, %s, %s, eps: %5.2f, pe: %6.2f' %
                          (code, current_date, last_report['announced_date'], last_report['eps'], pe),
                          flush=True)

                    update_requests.append(
                        UpdateOne(
                            {'code': code, 'date': current_date},
                            {'$set': {'code': code, 'date': current_date, 'pe': pe}}, upsert=True))

            if len(update_requests) > 0:
                save_result = self.collection.bulk_write(update_requests, ordered=False)
                print('股票代码: %s, 因子: %s, 插入:%4d, 更新: %4d' %
                      (code, self.name, save_result.upserted_count, save_result.modified_count), flush=True)
Esempio n. 4
0
    def __init__(self, strategy_option, begin_date=None, end_date=None):
        self.strategy_option = strategy_option
        if begin_date is None:
            self.begin_date = self.strategy_option.begin_date()
        else:
            self.begin_date = begin_date

        if end_date is None:
            self.end_date = self.strategy_option.end_date()
        else:
            self.end_date = end_date

        self.dm = DataModule()
        self.code_daily_cache = dict()
Esempio n. 5
0
    def __init__(self, strategy_option, begin_date=None, end_date=None):
        self.strategy_option = strategy_option
        if begin_date is None:
            self.begin_date = self.strategy_option.begin_date()
        else:
            self.begin_date = begin_date

        if end_date is None:
            self.end_date = self.strategy_option.end_date()
        else:
            self.end_date = end_date

        self.dm = DataModule()
        self.code_daily_cache = dict()

        self.logger = QuantLogger('backtest')
        self.candidatesLogger = QuantLogger('candidates')
    def compute(self, begin_date, end_date):
        codes = get_all_codes()
        dm = DataModule()

        for code in codes:
            df_daily = dm.get_k_data(code, begin_date=begin_date, end_date=end_date)

            if df_daily.index.size == 0:
                continue

            # 当日放量下跌
            df_daily['change'] = df_daily['close'] - df_daily['pre_close']
            df_daily = df_daily[df_daily['change'] < 0]
            df_daily['last_volume'] = df_daily['volume'].shift(1)
            df_daily.dropna(inplace=True)
            df_daily['volume_change'] = round(df_daily['volume']/df_daily['last_volume'], 2)
            df_daily = df_daily[df_daily['volume_change'] > 1.5]

            # 收的阴线实体不大
            df_daily['entity'] = round(abs((df_daily['open'] -df_daily['close'])) * 100/df_daily['close'], 2)
            df_daily = df_daily[df_daily['entity'] < 3]

            # 大部分时间在昨日之上运行
            df_daily.set_index(['date'], 1, inplace=True)

            update_requests = []
            for date in df_daily.index:

                # 大部分时间在昨日之上运行
                pre_close = df_daily.loc[date]['pre_close']
                df_minute = dm.get_k_data(code, period='M1', begin_date=date, end_date=date)
                df_minute = df_minute[df_minute['close'] > pre_close]

                if df_minute.index.size > 150:
                    update_requests.append(UpdateOne({
                        'code': code, 'date': date},
                        {'$set': {'code': code, 'date': date}},
                        upsert=True))

            if len(update_requests) > 0:
                save_result = self.collection.bulk_write(update_requests, ordered=False)
                print('股票代码: %s, 因子: %s, 插入:%4d, 更新: %4d' %
                      (code, self.name, save_result.upserted_count, save_result.modified_count), flush=True)
Esempio n. 7
0
    def is_stop(self, code, date):
        """
        判断股票在当前日期是否需要止损
        :param code: 股票代码
        :param date: 日期
        :return: True - 止损, False - 不止损
        """
        holding_stock = self.account.get_holding(code)
        print('止损判断:%s' % code, flush=True)
        print(holding_stock, flush=True)
        dm = DataModule()
        if holding_stock is not None:
            df_daily = dm.get_k_data(code, autype=None, begin_date=date, end_date=date)
            if df_daily.index.size > 0:
                df_daily.set_index(['date'], 1, inplace=True)

                profit = (holding_stock['volume'] * df_daily.loc[date]['close'] - holding_stock['cost']) \
                        * 100 / holding_stock['cost']

                return (profit < 0) & (abs(profit) >= abs(self.max_loss))

        return False
Esempio n. 8
0
    def compute(self, begin_date, end_date):
        print(self.name, flush=True)

        dm = DataModule()
        df_daily = dm.get_k_data()
        print(df_daily)
Esempio n. 9
0
    def get_option_stocks(self):
        """
        实现股票池选股逻辑,找到指定日期范围的候选股票
        条件:0 < PE < 30, 按从小到大排序,剔除停牌后,取前100个;再平衡周期:7个交易日
        :return: tuple,再平衡的日期列表,以及一个dict(key: 再平衡日, value: 当期的股票列表)
        """

        factor_module = FactorModule()
        dm = DataModule()

        # 因为上证指数没有停牌不会缺数,所以用它作为交易日历,
        szzz_hq_df = dm.get_k_data('000001',
                                   index=True,
                                   begin_date=self.begin_date,
                                   end_date=self.end_date)
        all_dates = list(szzz_hq_df['date'])

        # 缓存股票和其对应有交易的日期
        code_dates_cache = dict()

        # 调整日和其对应的股票
        rebalance_date_codes_dict = dict()
        rebalance_dates = []

        # 保存上一期的股票池
        last_phase_codes = []
        # 所有的交易日数
        dates_count = len(all_dates)
        # 用再平衡周期作为步长循环
        for index in range(0, dates_count, self.interval):
            # 当前的调整日
            rebalance_date = all_dates[index]

            # 获取本期符合条件的备选股票
            df_pe = factor_module.get_single_date_factors('pe', rebalance_date)
            df_pe.sort_values('pe', ascending=True, inplace=True)
            # 只保留小于30的数据
            df_pe = df_pe[(0 < df_pe['pe']) & (df_pe['pe'] < 30)]
            df_pe.set_index(['code'], inplace=True)
            this_phase_option_codes = list(df_pe.index)[0:100]
            print(this_phase_option_codes, flush=True)

            # 本期入选的股票代码列表
            this_phase_codes = []

            # 找到在上一期的股票池,但是当前停牌的股票,保留在当期股票池中
            if len(last_phase_codes) > 0:
                for code in last_phase_codes:
                    if code not in list(code_dates_cache.keys()):
                        daily_ks = dm.get_k_data(code,
                                                 autype=None,
                                                 begin_date=self.begin_date,
                                                 end_date=self.end_date)
                        daily_ks.set_index(['date'], inplace=True)
                        code_dates_cache[code] = list(daily_ks.index)
                    if rebalance_date not in code_dates_cache[code]:
                        this_phase_codes.append(code)

            print('上期停牌的股票:', flush=True)
            print(this_phase_codes, flush=True)

            # 剩余的位置用当前备选股票的
            option_size = len(this_phase_option_codes)
            if option_size > (100 - len(this_phase_codes)):
                this_phase_codes += this_phase_option_codes[
                    0:100 - len(this_phase_codes)]
            else:
                this_phase_codes += this_phase_option_codes

            # 当期股票池作为下次循环的上期股票池
            last_phase_codes = this_phase_codes

            # 保存到返回结果中
            rebalance_date_codes_dict[rebalance_date] = this_phase_codes
            rebalance_dates.append(rebalance_date)

            print('当前最终的备选票:%s' % rebalance_date, flush=True)
            print(this_phase_codes, flush=True)

        return rebalance_dates, rebalance_date_codes_dict
Esempio n. 10
0
    def compute(self, begin_date, end_date):
        """
        计算指定时间段内所有股票的该因子的值,并保存到数据库中
        :param begin_date:  开始时间
        :param end_date: 结束时间
        """
        dm = DataModule()

        # 获取所有股票
        codes = get_all_codes()

        for code in codes:
            print('计算市盈率, %s' % code)
            df_daily = dm.get_k_data(code,
                                     autype=None,
                                     begin_date=begin_date,
                                     end_date=end_date)

            if df_daily.index.size > 0:
                df_daily.set_index(['date'], 1, inplace=True)

                update_requests = []
                for date in df_daily.index:
                    finance_report = DB_CONN['finance_report'].find_one(
                        {
                            'code': code,
                            'report_date': {
                                '$regex': '\d{4}-12-31'
                            },
                            'announced_date': {
                                '$lte': date
                            }
                        },
                        sort=[('announced_date', DESCENDING)])

                    if finance_report is None:
                        continue

                    # 计算滚动市盈率并保存到daily_k中
                    eps = 0
                    if finance_report['eps'] != '-':
                        eps = finance_report['eps']

                    # 计算PE
                    if eps != 0:
                        pe = round(df_daily.loc[date]['close'] / eps, 3)

                        print('%s, %s, %s, eps: %5.2f, pe: %6.2f' %
                              (code, date, finance_report['announced_date'],
                               finance_report['eps'], pe),
                              flush=True)

                        update_requests.append(
                            UpdateOne({
                                'code': code,
                                'date': date
                            }, {
                                '$set': {
                                    'code': code,
                                    'date': date,
                                    'pe': pe
                                }
                            },
                                      upsert=True))

                if len(update_requests) > 0:
                    save_result = self.collection.bulk_write(update_requests,
                                                             ordered=False)
                    print('股票代码: %s, 因子: %s, 插入:%4d, 更新: %4d' %
                          (code, self.name, save_result.upserted_count,
                           save_result.modified_count),
                          flush=True)
Esempio n. 11
0
 def __init__(self):
     self.holding = dict()
     self.holding_codes = set()
     self.dm = DataModule()
    def analyze(self):
        # 初始化对数据管理子系统接口的调用
        dm = DataModule()
        # 初始化对因子管理子系统接口的调用
        fm = FactorModule()

        # 获取分析周期内的
        all_dates = get_trading_dates(self.begin_date, self.end_date)

        # 首档和末档,股票代码和后复权价格的Dictionary
        top_dailies = dict()
        bottom_dailies = dict()
        # 暂存上一个调整
        last_adjust_date = None

        # 设置沪深300的首日值
        hs300_k = dm.get_k_data('000300',
                                index=True,
                                begin_date=all_dates[0],
                                end_date=all_dates[0])
        self.hs300_first_value = hs300_k.loc[0]['close']

        # 计算每日收益
        for index in range(0, len(all_dates), self.interval):
            adjust_date = all_dates[index]

            # 获取因子值,按照指定的顺序排序
            df_factor = fm.get_single_date_factors(self.factor, adjust_date)
            if df_factor.index.size == 0:
                continue
            df_factor.sort_values(self.factor,
                                  ascending=self.ascending,
                                  inplace=True)
            # 将股票代码设为index
            df_factor.set_index(['code'], inplace=True)

            # 获取当日所有股票的行情
            df_dailies = dm.get_one_day_k_data(autype='hfq', date=adjust_date)
            # 将code设为index
            df_dailies.set_index(['code'], inplace=True)

            # 计算收益
            self.compute_profit(last_adjust_date, df_dailies, top_dailies,
                                bottom_dailies, adjust_date)

            # 删除停牌股票
            df_dailies = df_dailies[df_dailies['is_trading']]
            # 计算每当包含的股票数
            total_size = df_dailies.index.size
            single_position_count = int(total_size / self.position)

            # 调整首档组合
            self.adjust_top_position(top_dailies, df_factor, df_dailies,
                                     single_position_count)

            # 调整末档组合
            self.adjust_bottom_position(bottom_dailies, df_factor, df_dailies,
                                        single_position_count)

            # 保存上一个调整日
            last_adjust_date = adjust_date

        # 生成零投资组合的组合收益
        self.profit_df[
            'portfolio'] = self.profit_df['top'] - self.profit_df['bottom']

        self.draw()
    def compute_profit(self, last_adjust_date, df_dailies, top_dailies,
                       bottom_dailies, adjust_date):
        """
        计算收益
        :param last_adjust_date: 上一个调整日
        :param df_dailies:
        :param top_dailies:
        :param bottom_dailies:
        :param adjust_date: 当前调整日
        :return:
        """
        # 只有存在上一个调整日,才计算上期的收益
        if last_adjust_date is not None:
            # 计算首档收益
            top_profit = self.compute_average_profit(df_dailies, top_dailies)

            # 计算末档收益
            bottom_profit = self.compute_average_profit(
                df_dailies, bottom_dailies)

            # 计算组合收益
            portfolio_profit = top_profit[0] - bottom_profit[0]

            # 添加结果的DataFrame中
            self.profit_df.loc[last_adjust_date] = {
                'top': top_profit[0],
                'bottom': bottom_profit[0],
                'portfolio': portfolio_profit
            }

            # 计算累积收益(复利方式)
            # 首档
            top_cumulative_profit = round(
                (self.last_top_net_value *
                 (1 + top_profit[0] / 100) - 1) * 100, 2)
            self.last_top_net_value *= (1 + top_profit[0] / 100)
            # 末档
            bottom_cumulative_profit = round(
                (self.last_bottom_net_value *
                 (1 + bottom_profit[0] / 100) - 1) * 100, 2)
            self.last_bottom_net_value *= (1 + bottom_profit[0] / 100)
            # 组合
            portfolio_cumulative_profit = round(
                (self.last_portfolio_net_value *
                 (1 + portfolio_profit / 100) - 1) * 100, 2)
            self.last_portfolio_net_value *= (1 + portfolio_profit / 100)

            # 计算沪深300的累计收益
            dm = DataModule()
            hs300_k = dm.get_k_data('000300',
                                    index=True,
                                    begin_date=adjust_date,
                                    end_date=adjust_date)
            hs300_k.set_index(['date'], 1, inplace=True)
            hs300_profit = (hs300_k.loc[adjust_date]['close'] -
                            self.hs300_first_value) / self.hs300_first_value

            self.cumulative_profit.loc[last_adjust_date] = {
                'top': top_cumulative_profit,
                'bottom': bottom_cumulative_profit,
                'portfolio': portfolio_cumulative_profit,
                'hs300': hs300_profit
            }

            self.count_df.loc[last_adjust_date] = {
                'top': top_profit[1],
                'bottom': bottom_profit[1]
            }
Esempio n. 14
0
    def statistic_profit(self):
        """
        统计股票池的收益
        """
        # 设定评测周期
        rebalance_dates, codes_dict = self.get_option_stocks()

        dm = DataModule()

        # 用DataFrame保存收益
        df_profit = DataFrame(columns=['profit', 'hs300'])

        df_profit.loc[rebalance_dates[0]] = {'profit': 0, 'hs300': 0}

        # 获取沪深300在统计周期内的第一天的值
        hs300_k = dm.get_k_data('000300',
                                index=True,
                                begin_date=rebalance_dates[0],
                                end_date=rebalance_dates[0])
        hs300_begin_value = hs300_k.loc[hs300_k.index[0]]['close']

        # 通过净值计算累计收益
        net_value = 1
        for _index in range(1, len(rebalance_dates) - 1):
            last_rebalance_date = rebalance_dates[_index - 1]
            current_rebalance_date = rebalance_dates[_index]
            # 获取上一期的股票池
            codes = codes_dict[last_rebalance_date]

            # 统计当前的收益
            profit_sum = 0
            # 参与统计收益的股票个数
            profit_code_count = 0
            for code in codes:
                daily_ks = dm.get_k_data(code,
                                         autype='hfq',
                                         begin_date=last_rebalance_date,
                                         end_date=current_rebalance_date)

                index_size = daily_ks.index.size
                # 如果没有数据,则跳过,长期停牌
                if index_size == 0:
                    continue
                # 买入价
                in_price = daily_ks.loc[daily_ks.index[0]]['close']
                # 卖出价
                out_price = daily_ks.loc[daily_ks.index[index_size -
                                                        1]]['close']
                # 股票池内所有股票的收益
                profit_sum += (out_price - in_price) / in_price
                profit_code_count += 1

            profit = round(profit_sum / profit_code_count, 4)

            hs300_k_current = dm.get_k_data('000300',
                                            index=True,
                                            begin_date=current_rebalance_date,
                                            end_date=current_rebalance_date)
            hs300_close = hs300_k_current.loc[
                hs300_k_current.index[0]]['close']

            # 计算净值和累积收益
            net_value = net_value * (1 + profit)
            df_profit.loc[current_rebalance_date] = {
                'profit':
                round((net_value - 1) * 100, 4),
                'hs300':
                round((hs300_close - hs300_begin_value) * 100 /
                      hs300_begin_value, 4)
            }

            print(df_profit)

        # 绘制曲线
        df_profit.plot(title='Stock Pool Profit Statistic', kind='line')
        # 显示图像
        plt.show()
Esempio n. 15
0
    def compute(self, begin_date=None, end_date=None):
        """
        计算指定日期内的信号
        :param begin_date: 开始日期
        :param end_date: 结束日期
        """
        codes = get_all_codes()

        dm = DataModule()

        for code in codes:
            try:
                df_dailies = dm.get_k_data(code,
                                           autype='hfq',
                                           begin_date=begin_date,
                                           end_date=end_date)

                if df_dailies.index.size == 0:
                    continue

                # 计算MA10
                df_dailies['ma'] = df_dailies['close'].rolling(10).mean()
                # 计算当日收盘和MA10的差值
                df_dailies['delta'] = df_dailies['close'] - df_dailies['ma']

                # 删除不再使用的ma和close列
                df_dailies.drop(['ma', 'close'], 1, inplace=True)

                # 判断突破类型
                index_size = df_dailies.index.size
                breaks = [0]
                for index in range(1, index_size):
                    # 如果当前日期为停牌状态,则后面连续11日不参与计算
                    if df_dailies.loc[
                            df_dailies.index[index]]['is_trading'] is False:
                        count = 10
                        while count > 0:
                            index += 1
                            count -= 1
                            breaks.append(0)

                        index += 1

                    last = df_dailies.loc[df_dailies.index[index - 1]]['delta']
                    current = df_dailies.loc[df_dailies.index[index]]['delta']

                    # 向上突破设为1,向下突破设为-1,不是突破设为0
                    break_direction = 1 if last <= 0 < current else -1 if last >= 0 > current else 0
                    breaks.append(break_direction)

                # 设置突破信号
                df_dailies['break'] = breaks

                # 将日期作为索引
                df_dailies.set_index(['date'], 1, inplace=True)
                # 删除不再使用的trade_status和delta数据列
                df_dailies.drop(['is_trading', 'delta'], 1, inplace=True)
                # 只保留突破的日期
                df_dailies = df_dailies[df_dailies['break'] != 0]

                # 将信号保存到数据库
                update_requests = []
                for index in df_dailies.index:
                    doc = {
                        'code':
                        code,
                        'date':
                        index,
                        # 方向,向上突破 up,向下突破 down
                        'direction':
                        'up' if df_dailies.loc[index]['break'] == 1 else 'down'
                    }
                    update_requests.append(
                        UpdateOne(doc, {'$set': doc}, upsert=True))

                if len(update_requests) > 0:
                    update_result = self.collection.bulk_write(update_requests,
                                                               ordered=False)
                    print('%s, upserted: %4d, modified: %4d' %
                          (code, update_result.upserted_count,
                           update_result.modified_count),
                          flush=True)
            except:
                traceback.print_exc()
Esempio n. 16
0
 def __init__(self, account, strategy_option):
     BasePosition.__init__(self, account, strategy_option)
     self.dm = DataModule()
Esempio n. 17
0
 def __init__(self):
     self.dm = DataModule()
Esempio n. 18
0
 def __init__(self, account, max_loss):
     BaseStopLoss.__init__(self, account)
     self.max_loss = max_loss
     self.dm = DataModule()
Esempio n. 19
0
    def compute(self, begin_date=None, end_date=None):
        """
        计算指定时间段内所有股票的该因子的值,并保存到数据库中
        :param begin_date:  开始时间
        :param end_date: 结束时间
        """
        dm = DataModule()

        # 如果没有指定日期范围,则默认为计算当前交易日的数据
        if begin_date is None:
            begin_date = datetime.now().strftime('%Y-%m-%d')

        if end_date is None:
            end_date = datetime.now().strftime('%Y-%m-%d')

        dates = get_trading_dates(begin_date, end_date)

        for date in dates:
            # 查询出股票在某一交易日的总股本
            df_basics = dm.get_stock_basic_at(date)

            if df_basics.index.size == 0:
                continue

            # 将索引改为code
            df_basics.set_index(['code'], 1, inplace=True)

            # 查询出股票在某一个交易日的收盘价
            df_dailies = dm.get_one_day_k_data(autype=None, date=date)

            if df_dailies.index.size == 0:
                continue

            # 将索引设为code
            df_dailies.set_index(['code'], 1, inplace=True)

            update_requests = []
            for code in df_dailies.index:
                try:
                    # 股价
                    close = df_dailies.loc[code]['close']
                    # 总股本
                    total_shares = df_basics.loc[code]['totals']
                    # 总市值 = 股价 * 总股本
                    total_capital = round(close * total_shares, 2)

                    print('%s, %s, mkt_cap: %15.2f' %
                          (code, date, total_capital),
                          flush=True)

                    update_requests.append(
                        UpdateOne(
                            {'code': code, 'date': date},
                            {'$set': {'code': code, 'date': date, self.name: total_capital}}, upsert=True))

                except:
                    print('计算规模因子时发生异常,股票代码:%s,日期:%s'
                          % (code, date),
                          flush=True)

            if len(update_requests) > 0:
                save_result = self.collection.bulk_write(update_requests, ordered=False)
                print('股票代码: %s, 因子: %s, 插入:%4d, 更新: %4d' %
                      (code, self.name, save_result.upserted_count, save_result.modified_count), flush=True)
Esempio n. 20
0
 def __init__(self, begin_date, end_date):
     self.begin_date = begin_date
     self.end_date = end_date
     self.dm = DataModule()
     self.code_daily_cache = dict()
Esempio n. 21
0
 def __init__(self, account, max_profit, profit_drawdown):
     BaseStopProfit.__init__(self, account)
     self.max_profit = max_profit
     self.profit_drawdown = profit_drawdown
     self.dm = DataModule()
Esempio n. 22
0
    def compute(self, begin_date, end_date):
        """
        计算指定日期内的信号
        :param begin_date: 开始日期
        :param end_date: 结束日期
        """
        all_codes = get_all_codes()

        dm = DataModule()

        N = 20
        k = 2

        for code in all_codes:
            try:
                df_daily = dm.get_k_data(code,
                                         autype='hfq',
                                         begin_date=begin_date,
                                         end_date=end_date)

                # 计算MB,盘后计算,这里用当日的Close
                df_daily['MID'] = df_daily['close'].rolling(N).mean()
                # 计算STD20
                df_daily['std'] = df_daily['close'].rolling(N).std()
                # 计算UP
                df_daily['UP'] = df_daily['MID'] + k * df_daily['std']
                # 计算down
                df_daily['DOWN'] = df_daily['MID'] - k * df_daily['std']

                # 将日期作为索引
                df_daily.set_index(['date'], inplace=True)

                # 上轨和中轨右移一位
                shifted_up = df_daily['UP'].shift(1)
                shifted_middle = df_daily['MID'].shift(1)

                # 收盘价突破或者跌破中轨的幅度占上轨和中轨宽度的比例
                ref_line = (df_daily['close'] -
                            shifted_middle) / (shifted_up - shifted_middle)

                ref_prev = ref_line.shift(1)

                # 找到时间窗口内的最小值
                min_val = ref_line.rolling(10).min()

                # 找到时间窗口内最低点前的最大值
                max_leading_value = ref_line.rolling(10).apply(
                    lambda vec: vec[:np.argmin(vec) + 1].max().astype(float),
                    raw=True)

                # 中轨支撑的作用的范围
                delta = 0.15

                # 判断是否存在中轨支撑反弹的信号,要求:
                # 时间窗口的最低点之前的最大值大于delta,最小值的绝对值小于delta,就有一个穿越阈值分界线的动作;
                # 当前日期在也在阈值之上,表示又从最低点穿越到阈值分界线之上;
                # 而判断前一日在阈值分界线之下,表示穿越是在当前交易日完成
                m_rebound_mask = (abs(min_val) <= delta) & (ref_line > delta) & (ref_prev <= delta) & \
                                 (max_leading_value > delta)

                # 将信号保存到数据库
                update_requests = []
                df_daily['m_rebound_mask'] = m_rebound_mask
                df_daily = df_daily[df_daily['m_rebound_mask']]
                for date in df_daily.index:
                    doc = {'code': code, 'date': date, 'signal': 'mid_rebound'}
                    update_requests.append(
                        UpdateOne(doc, {'$set': doc}, upsert=True))

                if len(update_requests) > 0:
                    update_result = self.collection.bulk_write(update_requests,
                                                               ordered=False)
                    print('%s, upserted: %4d, modified: %4d' %
                          (code, update_result.upserted_count,
                           update_result.modified_count),
                          flush=True)
            except:
                traceback.print_exc()