量化分析之(二)均線多頭處理

對於碼農來說,只能上code了,可以選擇均線多點來判斷當前均線是否處於多頭狀態。

import copy
from gpx.common.gpc import *
import progressbar as pb

# logger = logging.getLogger('seq.' + __name__)

PROFIT_COLUMN = ['code', 'name', 'area', 'industry', 'roe',
                 'business_income', 'gross_profit_rate', 'profit', 'npr']

PERIOD_DOTS = {'period': gpc_period.DAY_30, 'dots': gpc_dots.FOUR}

THRESHOLD_PERIOD = 60


def save(df, name):
    return df.to_csv(name, encoding='utf_8_sig')


def retrieve(name):
    return pd.read_csv(name, encoding='utf_8_sig', index_col=0, dtype=object)

class gpc_line():
    def __init__(self, period_dots=PERIOD_DOTS):
        super(gpc_line, self).__init__()
        self._mean_df = pd.DataFrame()
        self._period_dots = period_dots

    def get_period(self):
        return self._period_dots['period']

    def get_dots(self):
        return self._period_dots['dots']

    def get_path(self, mode=gpc_handler.KEEP_UP):
        return 'keep_up.csv'

    def _up_dots(self, k_data, last_days=30, dots=gpc_dots.THREE):

        close = pd.Series(k_data.close)
        close_l = close.rolling(last_days).mean().tail(n=last_days)

        n = round(last_days * 2 / 3)

        if dots >= gpc_dots.BASE_LINE:

            if dots == gpc_dots.ONE_LINE:

                # close > n days average close
                _state = close.iloc[-1] > close_l.iloc[-1]

            else:

                # two line, compare two dot,
                # loc: -1, -n
                # every line close > mean close
                close_s = close.rolling(n).mean().tail(n=n)

                _state = close.iloc[-1] > close_s.iloc[-1] > 1.2 * close_l.iloc[-1] and \
                         close.iloc[-n] > close_s.iloc[-n] > 1.2 * close_l.iloc[-n]

        else:

            '''收紅盤'''
            if k_data.iloc[-1]['open'] > k_data.iloc[-1]['close']:
                return False, 0

            # k_data[_max] = tl.SMA(close, timeperiod=last_days)

            if dots == gpc_dots.ONE:

                '''檢測1個點來判斷均線是向上的'''
                _state = close.iloc[-1] > close_l.iloc[-1] > close_l.iloc[-n]

            elif dots == gpc_dots.THREE:
                '''檢測3個點來判斷均線是向上的'''
                _state = close_l.iloc[0] < close_l.iloc[n] < close_l.iloc[-1] and \
                         close_l.iloc[-1] > 1.2 * close_l.iloc[0]

            elif dots == gpc_dots.FOUR:

                '''檢測4個點來判斷均線是向上的'''
                m = round(last_days / 3)

                _state = close_l.iloc[0] < close_l.iloc[m] < close_l.iloc[n] < close_l.iloc[-1] and \
                         close_l.iloc[-1] > 1.2 * close_l.iloc[0]

            else:
                _state = False

        return _state, round(close_l.iloc[-1], 4)

    def is_keep_up(self, k_data, period, check_dots):
        return self._up_dots(k_data, period, check_dots)

    def filter_handler(self, in_code, handler_mode):
        period = self.get_period()
        all_code = copy.copy(in_code)
        ma_x = 'ma' + str(period)
        is_ma_x = 'is_' + ma_x
        all_code.loc[:, ma_x] = 0
        all_code.loc[:, is_ma_x] = False
        index, max_num = 0, len(all_code)
        logger.info(f'start, number = {max_num}, period = {period}')
        with pb.ProgressBar(max_value=max_num) as bar:
            for idx in all_code.index:
                try:
                    code = all_code.loc[idx, 'code']
                    k_data = ts.get_k_data(code)
                    if k_data is None: continue
                    if len(k_data.index) > period:
                        all_code.loc[idx, [is_ma_x, ma_x]] = \
                            self.is_keep_up(k_data, period, self.get_dots())
                except Exception as e:
                    logger.exception(e)
                bar.update(index)
                index += 1
        self._mean_df = all_code[all_code[is_ma_x]]
        if len(self._mean_df):
            logger.info(f'end, the result is {len(self._mean_df)}')
            save(self._mean_df, self.get_path(handler_mode))
            return self._mean_df

    def filter_result(self, all_code, mode=gpc_handler.KEEP_UP):
        over_ma_file = self.get_path(mode)
        logger.debug(f'mean path: {over_ma_file}')
        if os.path.exists(over_ma_file):
            code_df = retrieve(over_ma_file)
        else:
            code_df = self.filter_handler(all_code, handler_mode=mode)
        self.display_code(code_df)
        return code_df

    def display_code(self, loop_df):
        print('please input stocks list: ')
        _code_ = ''
        for idx in loop_df.index:
            _code_ += loop_df.loc[idx, 'code'] + ','
        print(f'\n{_code_}\n')


if __name__ == '__main__':
    gv = gpc_line()
    df = retrieve(r'stocks.csv')
    gv.filter_result(df)

 測試結果

DEBUG      2020-06-16 09:51:34,808 lesson2.py          [line:131 ] - mean path: keep_up.csv
please input stocks list: 

603605,603517,603345,600143,300767,300640,300607,300538,002127,

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章