Exemple #1
0
class PeriodSimulate(Simulate):
    def __init__(self, stock_codes, judge_out_name, period=7):
        super().__init__(stock_codes, judge_out_name)
        self.period = period

    @staticmethod
    def get_sum_field():
        return ['win_pct_less_than_50', 'win_pct_bigger_than_50', 'win_pct_bigger_than_60', 'win_pct_bigger_than_70']

    def __call__(self, *args, **kwargs):
        self.data_center = DataCenter()
        if self.stock_codes is None or len(self.stock_codes) == 0:
            return
        # 统计所有的股票,在:param peirod期间之内的盈利情况
        sum_dict = {
            'win_pct_less_than_50': 0,
            'win_pct_bigger_than_50': 0,
            'win_pct_bigger_than_60': 0,
            'win_pct_bigger_than_70': 0,
        }
        for stock_code in self.stock_codes:
            base_infos = self.data_center.fetch_base_data(stock_code)
            shift_close = base_infos['close'].shift(self.period)
            win_pct = (shift_close - base_infos['close']) / base_infos['close']
            base_infos['win_pct'] = win_pct
            base_infos.drop(['vol', 'amount', 'pre_close', 'change'], axis=1, inplace=True)
            if not base_infos.empty:
                count_percent = len(base_infos[base_infos['win_pct'] > 0]) / len(base_infos)
                sum_dict['win_pct_less_than_50'] = sum_dict['win_pct_less_than_50'] + 1 if count_percent < 0.5 \
                    else sum_dict['win_pct_less_than_50']
                sum_dict['win_pct_bigger_than_50'] = sum_dict['win_pct_bigger_than_50'] + 1 if count_percent >= 0.5 \
                    else sum_dict['win_pct_bigger_than_50']
                sum_dict['win_pct_bigger_than_60'] = sum_dict['win_pct_bigger_than_60'] + 1 if count_percent >= 0.6 \
                    else sum_dict['win_pct_bigger_than_60']
                sum_dict['win_pct_bigger_than_70'] = sum_dict['win_pct_bigger_than_70'] + 1 if count_percent >= 0.7 \
                    else sum_dict['win_pct_bigger_than_70']
                sum_str = "win count percent is " + str(count_percent)
                file_name = "period_simulate_" + stock_code
                now_time = datetime.datetime.now()
                now_time_str = now_time.strftime('%Y%m%d')
                file_name += '_' + now_time_str
                file_name += '.csv'
                FileOutput.csv_output(None, base_infos, file_name, spe_dir_name=self.judge_out_name,
                                      extra_content=sum_str)
        return sum_dict
Exemple #2
0
class Simulate:
    BUY_FLAG = 1
    SOLD_FLAG = -1
    DO_NOTHING = 0
    MULTI_INDI_BETWEEN = 5 # 如果有多种指标,多少天之内均发出买入信号就决定买入

    def __init__(self, stock_codes, judge_out_name, judge_time=None):
        self.initial_mny = None
        self.stock_codes = stock_codes
        self.judge_time = judge_time
        self.hold_num = 0  # 持仓手数
        self.left_mny = 0  # 剩余金额
        self.judge_out_name = judge_out_name  # 判定输出目录名称

    def set_registry(self, judge_time):
        self.judge_time = judge_time

    def set_judge_name(self, judge_name):
        self.judge_out_name = judge_name

    def set_init_mny(self, init_mny):
        """
        设置初始金额,金额为RMB
        :param init_mny:
        :return:
        """
        self.initial_mny = init_mny
        self.left_mny = init_mny

    def reset(self):
        self.left_mny = self.initial_mny
        self.hold_num = 0

    def __call__(self, *args, **kwargs):
        # TODO -- 看一下Python的数值计算方式,是否有小数???
        self.data_center = DataCenter()
        final_sum_dict = {
            'win_num': 0,
            'lose_num': 0,
            'max_win_pct': 0,
            'max_lost_pct': 0,
            'ave_win_mny': 0
        }
        trade_rst = pandas.DataFrame(columns=('ts_code', 'trade_times', 'final_win', 'win_pct'))
        for stock_code in self.stock_codes:
            trade_rst_dict = {
                'ts_code': stock_code,
                'trade_times': 0,
                'final_win': 0,
                'win_pct': 0
            }
            base_infos = self.data_center.fetch_base_data(stock_code)

            if base_infos is None or len(base_infos) == 0:
                continue

            ret_time = []
            for item in self.judge_time:
                ret_time.append(item(base_infos))
            if ret_time is None or len(ret_time) == 0:
                continue
            detail_trade_info = pandas.DataFrame(
                columns=('ts_code', 'curr_close', 'trade_date', 'trade_num', 'hold_num', 'hold_mny',
                         'total_mny'))
            if len(ret_time[0]) != len(base_infos):
                print("Not equals!!!")
            for i in range(len(ret_time[0])):
                # 判定是否是买入时机
                operate_flag = self.DO_NOTHING
                temp_buy_pct = 0.1
                for item in ret_time:
                    # 从当前往前5天之内是否有发出过买入信号,如果有,就算有
                    start_index = i - self.MULTI_INDI_BETWEEN
                    start_index = 0 if start_index < 0 else start_index
                    temp_val = self.DO_NOTHING
                    for j in range(start_index, i + 1):
                        if item.at[j, 'flag'] == self.BUY_FLAG:
                            temp_val = self.BUY_FLAG
                            temp_buy_pct = item.at[j, 'percent'] if 0 < item.at[j, 'percent'] < temp_buy_pct \
                                else temp_buy_pct
                            break
                        elif item.at[j, 'flag'] == self.SOLD_FLAG:
                            temp_val = self.SOLD_FLAG
                            temp_buy_pct = item.at[j, 'percent'] if 0 < item.at[j, 'percent'] < temp_buy_pct \
                                else temp_buy_pct
                            break
                    if operate_flag == self.DO_NOTHING or operate_flag == temp_val:
                        operate_flag = temp_val
                        continue
                    else:
                        operate_flag = self.DO_NOTHING
                        break

                if operate_flag == self.BUY_FLAG:
                    # 默认买入10%
                    buy_pct = temp_buy_pct
                    buy_mny = self.initial_mny * buy_pct
                    buy_mny = self.left_mny if self.left_mny < buy_mny else buy_mny
                    buy_num = buy_mny / base_infos.at[i, 'close']
                    self.hold_num = self.hold_num + buy_num
                    self.left_mny = self.left_mny - buy_mny
                    hold_mny = self.hold_num * base_infos.at[i, 'close']
                    # 记录买入信息
                    temp_dict = {
                        'ts_code': stock_code,
                        'trade_date': base_infos.at[i, 'trade_date'],
                        'trade_num': buy_num,
                        'hold_num': self.hold_num,
                        'hold_mny': hold_mny,
                        'total_mny': self.left_mny + hold_mny,
                        'curr_close': base_infos.at[i, 'close']
                    }
                    detail_trade_info = detail_trade_info.append(temp_dict, ignore_index=True)
                    trade_rst_dict['trade_times'] = trade_rst_dict['trade_times'] + 1
                elif operate_flag == self.SOLD_FLAG:
                    # 默认卖出持仓数量的10%
                    sold_pct = temp_buy_pct
                    sold_num = self.hold_num * sold_pct
                    sold_num = sold_num / 100 * 100
                    self.hold_num = self.hold_num - sold_num
                    sold_mny = sold_num * base_infos.at[i, 'close']
                    self.left_mny = self.left_mny + sold_mny
                    hold_mny = self.hold_num * base_infos.at[i, 'close']
                    # 记录卖出信息
                    temp_dict = {
                        'ts_code': stock_code,
                        'trade_date': base_infos.at[i, 'trade_date'],
                        'trade_num': sold_num,
                        'hold_num': self.hold_num,
                        'hold_mny': hold_mny,
                        'total_mny': self.left_mny + hold_mny,
                        'curr_close': base_infos.at[i, 'close']
                    }
                    detail_trade_info = detail_trade_info.append(temp_dict, ignore_index=True)
                    trade_rst_dict['trade_times'] = trade_rst_dict['trade_times'] + 1
            if not detail_trade_info.empty:
                file_name = "simulate_" + str(stock_code)
                now_time = datetime.datetime.now()
                now_time_str = now_time.strftime('%Y%m%d')
                file_name += '_' + now_time_str
                file_name += '.csv'
                FileOutput.csv_output(None, detail_trade_info, file_name, spe_dir_name=self.judge_out_name)
            else:
                print("no such stock!")
            self.reset()
            if detail_trade_info.empty:
                continue
            # 统计该只股票的最终盈利
            last_win = detail_trade_info.at[(len(detail_trade_info) - 1), 'total_mny'] - self.initial_mny
            last_win_pct = last_win / self.initial_mny
            trade_rst_dict['final_win'] = last_win
            trade_rst_dict['win_pct'] = last_win_pct
            trade_rst = trade_rst.append(trade_rst_dict, ignore_index=True)

            # 统计多只股票的汇总
            final_sum_dict['win_num'] = final_sum_dict['win_num'] + 1 if last_win > 0 else final_sum_dict['win_num']
            final_sum_dict['lose_num'] = final_sum_dict['lose_num'] + 1 if last_win <= 0 else final_sum_dict['lose_num']
            final_sum_dict['max_win_pct'] = last_win_pct if last_win_pct > final_sum_dict['max_win_pct'] else \
                final_sum_dict['max_win_pct']
            final_sum_dict['max_lost_pct'] = last_win_pct if last_win_pct <= final_sum_dict['max_lost_pct'] else \
                final_sum_dict['max_lost_pct']

        sum_str = "获利数量:" + str(final_sum_dict['win_num']) + " 损失数量:" + str(final_sum_dict['lose_num']) \
                  + " 最大获利百分比:" + str(final_sum_dict['max_win_pct']) + " 最大损失百分比:" + \
                  str(final_sum_dict['max_lost_pct'])
        if not trade_rst.empty:
            file_name = "trade_group_" + self.stock_codes[0]
            now_time = datetime.datetime.now()
            now_time_str = now_time.strftime('%Y%m%d')
            file_name += '_' + now_time_str
            file_name += '.csv'
            FileOutput.csv_output(None, trade_rst, file_name, spe_dir_name=self.judge_out_name, extra_content=sum_str)
        return final_sum_dict
Exemple #3
0
class MACDSelector:
    """
    通过MACD指标来选择对应的股票
    """

    BUY_SIGNAL_PERIOD = 2  # 两天之内发出买入信号的话,该只股票视为可买入

    def __init__(self, ts_codes=None):
        if ts_codes is None:
            ts_codes = []
        self.ts_codes = ts_codes
        self.fast = 12
        self.slow = 26
        self.signal = 9

    def set_fast(self, fast):
        self.fast = fast

    def set_slow(self, slow):
        self.slow = slow

    def set_signal(self, signal):
        self.signal = signal

    def __call__(self, *args, **kwargs):
        self.data_center = DataCenter()
        if len(self.ts_codes) == 0:
            return

        result = pandas.DataFrame(columns=('ts_code', 'in_price', 'in_date',
                                           'origin_from', 'in_reason',
                                           'finished', 'manual'))
        for ts_code in self.ts_codes:
            field_suffix = "_" + str(self.fast) + "_" + str(
                self.slow) + "_" + str(self.signal)
            macd_field_name = 'MACD' + field_suffix
            histogram_field_name = 'MACDh' + field_suffix
            signal_field_name = 'MACDs' + field_suffix
            base_infos = self.data_center.fetch_base_data(ts_code)
            if base_infos is None or len(base_infos) == 0:
                continue
            close = base_infos['close']
            macd_ret = ta.macd(close, self.fast, self.slow, signal=self.signal)
            if len(macd_ret) < 2:
                continue
            rst_length = len(macd_ret)
            start_index = min(rst_length, self.BUY_SIGNAL_PERIOD)
            start_index = rst_length - start_index
            low_flag = False
            for i in range(start_index, rst_length):
                if macd_ret.at[i, macd_field_name] is not None and macd_ret.at[i, signal_field_name] is not None and \
                        macd_ret.at[i, macd_field_name] < macd_ret.at[i, signal_field_name]:
                    low_flag = True
                else:
                    if low_flag:
                        now_time = datetime.datetime.now()
                        now_time_str = now_time.strftime('%Y%m%d')
                        temp_dict = {
                            'ts_code': ts_code,
                            'in_price': close[i],
                            'in_date': base_infos.at[start_index,
                                                     'trade_date'],
                            'origin_from': 'macd',
                            'in_reason': 'macd金叉',
                            'finished': 0,
                            'manual': 0
                        }
                        result = result.append(temp_dict, ignore_index=True)
        return result