Example #1
0
class CReivew:
    def __init__(self, dbinfo=ct.DB_INFO, redis_host=None):
        self.dbinfo = dbinfo
        self.logger = getLogger(__name__)
        self.tu_client = get_tushare_client()
        self.doc = CDoc()
        self.redis = create_redis_obj(
        ) if redis_host is None else create_redis_obj(redis_host)
        self.mysql_client = CMySQL(dbinfo, iredis=self.redis)
        self.margin_client = Margin(dbinfo=dbinfo, redis_host=redis_host)
        self.rstock_client = RIndexStock(dbinfo=dbinfo, redis_host=redis_host)
        self.sh_market_client = StockExchange(ct.SH_MARKET_SYMBOL)
        self.sz_market_client = StockExchange(ct.SZ_MARKET_SYMBOL)
        self.emotion_client = Emotion()

    def get_industry_data(self, cdate):
        ri = RIndexIndustryInfo()
        df = ri.get_k_data(cdate)
        if df.empty: return df
        df = df.reset_index(drop=True)
        df = df.sort_values(by='amount', ascending=False)
        df['money_change'] = (df['amount'] - df['preamount']) / 1e8
        industry_info = IndustryInfo.get()
        df = pd.merge(df, industry_info, how='left', on=['code'])
        return df

    def get_index_data(self, cdate):
        df = pd.DataFrame()
        for code, name in ct.TDX_INDEX_DICT.items():
            data = CIndex(code).get_k_data(cdate)
            data['name'] = name
            data['code'] = code
            df = df.append(data)
        df = df.reset_index(drop=True)
        return df

    def get_market_data(self, market, start_date, end_date):
        if market == ct.SH_MARKET_SYMBOL:
            df = self.sh_market_client.get_k_data_in_range(
                start_date, end_date)
            df = df.loc[df.name == '上海市场']
        else:
            df = self.sz_market_client.get_k_data_in_range(
                start_date, end_date)
            df = df.loc[df.name == '深圳市场']
        df = df.round(2)
        df = df.drop_duplicates()
        df = df.reset_index(drop=True)
        df = df.sort_values(by='date', ascending=True)
        df.negotiable_value = (df.negotiable_value / 2).astype(int)
        return df

    def get_rzrq_info(self, market, start_date, end_date):
        df = self.margin_client.get_k_data_in_range(start_date, end_date)
        if market == ct.SH_MARKET_SYMBOL:
            df = df.loc[df.code == 'SSE']
            df['code'] = '上海市场'
        else:
            df = df.loc[df.code == 'SZSE']
            df['code'] = '深圳市场'
        df = df.round(2)
        df['rzye'] = df['rzye'] / 1e+8
        df['rzmre'] = df['rzmre'] / 1e+8
        df['rzche'] = df['rzche'] / 1e+8
        df['rqye'] = df['rqye'] / 1e+8
        df['rzrqye'] = df['rzrqye'] / 1e+8
        df = df.drop_duplicates()
        df = df.reset_index(drop=True)
        df = df.sort_values(by='date', ascending=True)
        return df

    def get_index_df(self, code, start_date, end_date):
        cindex_client = CIndex(code)
        df = cindex_client.get_k_data_in_range(start_date, end_date)
        df['time'] = df.index.tolist()
        df = df[[
            'time', 'open', 'high', 'low', 'close', 'volume', 'amount', 'date'
        ]]
        return df

    def update(self, cdate=datetime.now().strftime('%Y-%m-%d')):
        start_date = get_day_nday_ago(cdate, 100, dformat="%Y-%m-%d")
        end_date = cdate
        try:
            #market info
            sh_df = self.get_market_data(ct.SH_MARKET_SYMBOL, start_date,
                                         end_date)
            sz_df = self.get_market_data(ct.SZ_MARKET_SYMBOL, start_date,
                                         end_date)
            date_list = list(
                set(sh_df.date.tolist()).intersection(set(
                    sz_df.date.tolist())))
            sh_df = sh_df[sh_df.date.isin(date_list)]
            sh_df = sh_df.reset_index(drop=True)
            sz_df = sz_df[sz_df.date.isin(date_list)]
            sz_df = sz_df.reset_index(drop=True)
            #rzrq info
            sh_rzrq_df = self.get_rzrq_info(ct.SH_MARKET_SYMBOL, start_date,
                                            end_date)
            sz_rzrq_df = self.get_rzrq_info(ct.SZ_MARKET_SYMBOL, start_date,
                                            end_date)
            date_list = list(
                set(sh_rzrq_df.date.tolist()).intersection(
                    set(sz_rzrq_df.date.tolist())))
            sh_rzrq_df = sh_rzrq_df[sh_rzrq_df.date.isin(date_list)]
            sh_rzrq_df = sh_rzrq_df.reset_index(drop=True)
            sz_rzrq_df = sz_rzrq_df[sz_rzrq_df.date.isin(date_list)]
            sz_rzrq_df = sz_rzrq_df.reset_index(drop=True)
            #average price info
            av_df = self.get_index_df('880003', start_date, end_date)
            #limit up and down info
            limit_info = CLimit(self.dbinfo).get_data(cdate)
            stock_info = self.rstock_client.get_data(cdate)
            stock_info = stock_info[stock_info.volume >
                                    0]  #get volume > 0 stock list
            stock_info = stock_info.reset_index(drop=True)
            #index info
            index_info = self.get_index_data(end_date)
            #industry analysis
            industry_info = self.get_industry_data(cdate)
            #all stock info
            all_stock_info = self.rstock_client.get_k_data_in_range(
                start_date, end_date)
            #gen review file and make dir for new data
            self.doc.generate(cdate, sh_df, sz_df, sh_rzrq_df, sz_rzrq_df,
                              av_df, limit_info, stock_info, industry_info,
                              index_info, all_stock_info)
            ##gen review animation
            #self.gen_animation()
        except Exception as e:
            self.logger.error(e)
            traceback.print_exc()

    def gen_animation(self, sfile=None):
        style.use('fivethirtyeight')
        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=1, metadata=dict(artist='biek'), bitrate=1800)
        fig = plt.figure()
        ax = fig.add_subplot(1, 1, 1)
        _today = datetime.now().strftime('%Y-%m-%d')
        cdata = self.mysql_client.get('select * from %s where date = "%s"' %
                                      (ct.ANIMATION_INFO, _today))
        if cdata is None: return None
        cdata = cdata.reset_index(drop=True)
        ctime_list = cdata.time.unique()
        name_list = cdata.name.unique()
        ctime_list = [
            datetime.strptime(ctime, '%H:%M:%S') for ctime in ctime_list
        ]
        frame_num = len(ctime_list)
        if 0 == frame_num: return None

        def animate(i):
            ax.clear()
            ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
            ax.xaxis.set_major_locator(mdates.DayLocator())
            ax.set_title('盯盘', fontproperties=get_chinese_font())
            ax.set_xlabel('时间', fontproperties=get_chinese_font())
            ax.set_ylabel('增长', fontproperties=get_chinese_font())
            ax.set_ylim((-6, 6))
            fig.autofmt_xdate()
            for name in name_list:
                pchange_list = list()
                price_list = cdata[cdata.name == name]['price'].tolist()
                pchange_list.append(0)
                for _index in range(1, len(price_list)):
                    pchange_list.append(
                        10 * (price_list[_index] - price_list[_index - 1]) /
                        price_list[0])
                ax.plot(ctime_list[0:i],
                        pchange_list[0:i],
                        label=name,
                        linewidth=1.5)
                if pchange_list[i - 1] > 1 or pchange_list[i - 1] < -1:
                    ax.text(ctime_list[i - 1],
                            pchange_list[i - 1],
                            name,
                            font_properties=get_chinese_font())

        ani = animation.FuncAnimation(fig,
                                      animate,
                                      frame_num,
                                      interval=60000,
                                      repeat=False)
        sfile = '/data/animation/%s_animation.mp4' % _today if sfile is None else sfile
        ani.save(sfile, writer)
        plt.close(fig)
Example #2
0
class MarauderMap():
    def __init__(self):
        self.ris = RIndexStock()
        self.logger = getLogger(__name__)

    def get_data(self, mdate):
        return self.ris.get_data(mdate)

    def plot(self, cdate, fdir, fname):
        df = self.ris.get_data(cdate)
        if df.empty: return
        fig, ax = plt.subplots()
        #get min profit day
        min_pday = df.pday.values.min()
        max_pday = df.pday.values.max()
        #get max profit day
        min_profit = df.profit.values.min()
        max_profit = df.profit.values.max()
        #set axis for map
        xmax = max(abs(min_pday), max_pday)
        ymax = max(abs(min_profit), max_profit)

        ax.set_xlim(-xmax, xmax)
        ax.set_ylim(-ymax, ymax)
        ax.spines['top'].set_color('none')
        ax.spines['right'].set_color('none')
        ax.xaxis.set_ticks_position('bottom')
        ax.spines['bottom'].set_position(('data', 0))
        ax.yaxis.set_ticks_position('left')
        ax.spines['left'].set_position(('data', 0))
        for code in df.code.tolist():
            pday = df.loc[df.code == code, 'pday']
            profit = df.loc[df.code == code, 'profit']
            ax.scatter(pday, profit, s=5, alpha=1, linewidths=0.1)
        plt.savefig('%s/%s.png' % (fdir, fname), dpi=1000)

    def gen_animation(self, end_date, days):
        import matplotlib.animation as animation
        matplotlib.use('Agg')
        start_date = get_day_nday_ago(end_date, num=days, dformat="%Y-%m-%d")
        df = self.ris.get_k_data_in_range(start_date, end_date)
        fig, ax = plt.subplots()
        #get min profit day
        min_pday = df.pday.values.min()
        max_pday = df.pday.values.max()
        #get max profit day
        min_profit = df.profit.values.min()
        max_profit = df.profit.values.max()
        #set axis for map
        xmax = max(abs(min_pday), max_pday)
        ymax = max(abs(min_profit), max_profit)
        groups = df.groupby(df.date)
        dates = list(set(df.date.tolist()))
        dates.sort()
        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=2, metadata=dict(artist='biek'), bitrate=-1)

        def init():
            ax.clear()
            ax.set_xlim(-xmax, xmax)
            ax.set_ylim(-ymax, ymax)
            ax.spines['top'].set_color('none')
            ax.spines['right'].set_color('none')
            ax.xaxis.set_ticks_position('bottom')
            ax.spines['bottom'].set_position(('data', 0))
            ax.yaxis.set_ticks_position('left')
            ax.spines['left'].set_position(('data', 0))

        def animate(i):
            cdate = dates[i]
            df = groups.get_group(cdate)
            init()
            print(cdate, len(df))
            bull_stock_num = len(df[df.profit >= 0])
            for code in df.code.tolist():
                pday = df.loc[df.code == code, 'pday']
                profit = df.loc[df.code == code, 'profit']
                ax.scatter(pday, profit, color='black', s=1)
                ax.set_title("日期:%s 股票总数:%s 牛熊股比:%s" %
                             (cdate, len(df), 100 * bull_stock_num / len(df)),
                             fontproperties=get_chinese_font())

        ani = animation.FuncAnimation(fig,
                                      animate,
                                      frames=len(dates),
                                      init_func=init,
                                      interval=1000,
                                      repeat=False)
        sfile = '/code/panimation.mp4'
        ani.save(sfile, writer)
        ax.set_title('Marauder Map for date')
        ax.grid(True)
        plt.close(fig)
Example #3
0
    elif code in black_set:
        return -1
    else:
        return 0


#if __name__ == '__main__':
#    mval_client = MValuation()
#    mval_client.update_index(end_date = '2019-08-13')

if __name__ == '__main__':
    try:
        mdate = 20190815
        mval_client = MValuation()
        rindex_client = RIndexStock()
        df = rindex_client.get_data(transfer_int_to_date_string(mdate))
        df['mv'] = df['totals'] * df['close']
        df['mv'] = df['mv'] / 100000000
        df = df[df.mv > 100]
        df = df[(df.profit > 1) & (df.profit < 6.5)]
        #黑名单
        black_set = set(ct.BLACK_DICT.keys())
        white_set = set(ct.WHITE_DICT.keys())
        if len(black_set.intersection(white_set)) > 0:
            raise Exception("black and white has intersection.")
        df['history'] = df.apply(
            lambda row: get_hist_val(black_set, white_set, row['code']),
            axis=1)
        df = df[df['history'] > -1]
        #basic_info
        base_df = mval_client.stock_info_client.get()
Example #4
0
import traceback
import const as ct
import pandas as pd
from rstock import RIndexStock
from cstock_info import CStockInfo
from industry_info import IndustryInfo
if __name__ == '__main__':
    try:
        mdate = '2019-08-02'
        cobj = CStockInfo()
        robj = RIndexStock()
        iobj = IndustryInfo()
        black_list = list(ct.BLACK_DICT.keys())

        bdf = cobj.get()
        stock_info = robj.get_data(mdate)
        idf = iobj.get_csi_industry_data(mdate)
        df = pd.merge(bdf, idf, how='left', on=['code'])
        df = pd.merge(stock_info, df, how='inner', on=['code'])
        df = df[~df.code.isin(black_list)]
        df = df[(df.profit > 1) & (df.profit < 3) & (df.pday > 30) &
                (df.timeToMarket < 20150101)]
        df = df.reset_index(drop=True)
        #df = df[['code', 'name', 'industry', 'profit', 'pday', 'pind_name', 'sind_name', 'tind_name', 'find_name']]
        df = df[['code', 'name', 'profit', 'pday', 'find_name']]
        for name, contains in df.groupby('find_name'):
            if len(contains) > 2:
                print("--------------------")
                print(name)
                print(contains)
                print("====================")
Example #5
0
class MarauderMap():
    def __init__(self, code_list):
        self.codes = code_list
        self.ris = RIndexStock()
        self.logger = getLogger(__name__)

    def plot(self, cdate, fdir, fname):
        df = self.ris.get_data(cdate)

        if df.empty: return
        fig, ax = plt.subplots()
        #get min profit day
        min_pday = df.pday.values.min()
        max_pday = df.pday.values.max()
        #get max profit day
        min_profit = df.profit.values.min()
        max_profit = df.profit.values.max()
        #set axis for map
        xmax = max(abs(min_pday), max_pday)
        ymax = max(abs(min_profit), max_profit)

        ax.set_xlim(-xmax, xmax)
        ax.set_ylim(-ymax, ymax)
        ax.spines['top'].set_color('none')
        ax.spines['right'].set_color('none')
        ax.xaxis.set_ticks_position('bottom')
        ax.spines['bottom'].set_position(('data', 0))
        ax.yaxis.set_ticks_position('left')
        ax.spines['left'].set_position(('data', 0))

        for code in self.codes:
            pday = df.loc[df.code == code, 'pday']
            profit = df.loc[df.code == code, 'profit']
            ax.scatter(pday, profit, s=5, alpha=1, linewidths=0.1)
        plt.savefig('%s/%s.png' % (fdir, fname), dpi=1000)

    def gen_animation(self, cdate):
        df = self.get_data(cdate)
        fig, ax = plt.subplots()

        Writer = animation.writers['ffmpeg']
        writer = Writer(fps=30, metadata=dict(artist='biek'), bitrate=1800)

        #get min profit day
        min_pday = df.pday.values.min()
        max_pday = df.pday.values.max()
        #get max profit day
        min_profit = df.profit.values.min()
        max_profit = df.profit.values.max()
        #set axis for map

        xmax = max(abs(min_pday), max_pday)
        ymax = max(abs(min_profit), max_profit)
        groups = list(df.groupby(df.time))

        def init():
            ax.clear()
            ax.set_xlim(-xmax, xmax)
            ax.set_ylim(-ymax, ymax)
            ax.spines['top'].set_color('none')
            ax.spines['right'].set_color('none')
            ax.xaxis.set_ticks_position('bottom')
            ax.spines['bottom'].set_position(('data', 0))
            ax.yaxis.set_ticks_position('left')
            ax.spines['left'].set_position(('data', 0))

        def animate(n):
            val = groups[n][1].values.tolist()[0]
            for code in self.codes:
                pday = val[1]
                profit = val[2]
                ax.scatter(pday, profit, s=5, alpha=1, linewidths=0.1)

        ani = animation.FuncAnimation(fig,
                                      animate,
                                      frames=300,
                                      init_func=init,
                                      interval=1,
                                      repeat=False)
        sfile = '/code/animation.mp4'
        ani.save(sfile, writer, fps=60, dpi=100)
        ax.set_title('Marauder Map for date')
        ax.grid(True)
        plt.close(fig)
Example #6
0
class BullStockRatio:
    def __init__(self, index_code, dbinfo=ct.DB_INFO, redis_host=None):
        self.dbinfo = dbinfo
        self.index_code = index_code
        self.index_obj = CIndex(index_code,
                                dbinfo=self.dbinfo,
                                redis_host=redis_host)
        self.db_name = self.index_obj.get_dbname(index_code)
        self.logger = getLogger(__name__)
        self.ris = RIndexStock(dbinfo, redis_host)
        self.bull_stock_ratio_table = self.get_table_name()
        self.redis = create_redis_obj(
        ) if redis_host is None else create_redis_obj(redis_host)
        self.mysql_client = CMySQL(self.dbinfo,
                                   dbname=self.db_name,
                                   iredis=self.redis)
        if not self.create(): raise Exception("create emotion table failed")

    def delete(self):
        self.mysql_client.delete(self.bull_stock_ratio_table)

    def get_table_name(self):
        return "%s_%s" % (self.db_name, ct.BULLSTOCKRATIO_TABLE)

    def create(self):
        if self.bull_stock_ratio_table not in self.mysql_client.get_all_tables(
        ):
            sql = 'create table if not exists %s(date varchar(10) not null, ratio float, PRIMARY KEY (date))' % self.bull_stock_ratio_table
            if not self.mysql_client.create(sql, self.bull_stock_ratio_table):
                return False
        return True

    def is_date_exists(self, table_name, cdate):
        if self.redis.exists(table_name):
            return cdate in set(
                str(tdate, encoding=ct.UTF8)
                for tdate in self.redis.smembers(table_name))
        return False

    def get_k_data_between(self, start_date, end_date):
        sql = "select * from %s where date between \"%s\" and \"%s\"" % (
            self.get_table_name(), start_date, end_date)
        return self.mysql_client.get(sql)

    def get_components(self, cdate):
        df = self.index_obj.get_components_data(cdate)
        if df is None: return list()
        if df.empty: return list()
        if self.index_code == '000001': df = df[df.code.str.startswith('6')]
        return df.code.tolist()

    def get_data(self, cdate):
        return self.ris.get_data(cdate)

    def update(self, end_date=None, num=30):
        if end_date is None: end_date = datetime.now().strftime('%Y-%m-%d')
        #start_date = "1997-12-30"
        start_date = get_day_nday_ago(end_date, num=num, dformat="%Y-%m-%d")
        succeed = True
        code_list = self.get_components(end_date)
        if 0 == len(code_list):
            self.logger.error("%s code_list for %s is empty" %
                              (end_date, self.index_code))
            return False
        for mdate in get_dates_array(start_date, end_date):
            if CCalendar.is_trading_day(mdate, redis=self.redis):
                if not self.set_ratio(code_list, mdate):
                    self.logger.error("set %s score for %s set failed" %
                                      (self.index_code, mdate))
                    succeed = False
        return succeed

    def get_profit_stocks(self, df):
        data = df[df.profit >= 0]
        return data.code.tolist()

    def set_ratio(self,
                  now_code_list,
                  cdate=datetime.now().strftime('%Y-%m-%d')):
        if self.is_date_exists(self.bull_stock_ratio_table, cdate):
            self.logger.debug("existed date:%s, date:%s" %
                              (self.bull_stock_ratio_table, cdate))
            return True
        code_list = self.get_components(cdate)
        if len(code_list) == 0: code_list = now_code_list
        df = self.get_data(cdate)
        if df is None: return False
        if df.empty: return False
        df = df[df.code.isin(code_list)]
        if df.empty: return True
        profit_code_list = self.get_profit_stocks(df)
        bull_stock_num = len(profit_code_list)
        bull_ration = 100 * bull_stock_num / len(df)
        data = {'date': [cdate], 'ratio': [bull_ration]}
        df = pd.DataFrame.from_dict(data)
        if self.mysql_client.set(df, self.bull_stock_ratio_table):
            return self.redis.sadd(self.bull_stock_ratio_table, cdate)
        return False
Example #7
0
class Emotion:
    def __init__(self, dbinfo = ct.DB_INFO, redis_host = None):
        self.dbinfo = dbinfo
        self.emotion_table = ct.EMOTION_TABLE
        self.redis = create_redis_obj() if redis_host is None else create_redis_obj(redis_host)
        self.mysql_client = CMySQL(self.dbinfo, iredis = self.redis)
        self.rstock_client = RIndexStock(dbinfo, redis_host)
        self.logger = getLogger(__name__)
        if not self.create(): raise Exception("create emotion table failed")

    def create(self):
        if self.emotion_table not in self.mysql_client.get_all_tables():
            sql = 'create table if not exists %s(date varchar(10) not null, score float, PRIMARY KEY (date))' % self.emotion_table 
            if not self.mysql_client.create(sql, self.emotion_table): return False
        return True

    def get_score(self, cdate = None):
        if cdate is None:
            sql = "select * from %s" % self.emotion_table
        else:
            sql = "select * from %s where date=\"%s\"" %(self.emotion_table, cdate)
        return self.mysql_client.get(sql)

    def get_stock_data(self, cdate):
        df_byte = self.redis.get(ct.TODAY_ALL_STOCK)
        if df_byte is None: return None
        df = _pickle.loads(df_byte)
        return df.loc[df.date == date]

    def update(self, end_date = None, num = 3):
        if end_date is None: end_date = datetime.now().strftime('%Y-%m-%d')
        start_date = get_day_nday_ago(end_date, num = num, dformat = "%Y-%m-%d")
        succeed = True
        for mdate in get_dates_array(start_date, end_date):
            if CCalendar.is_trading_day(mdate, redis = self.redis):
                if not self.set_score(mdate):
                    succeed = False
                    self.logger.info("set score for %s set failed" % mdate)
        return succeed

    def set_score(self, cdate = datetime.now().strftime('%Y-%m-%d')):
        stock_info = self.rstock_client.get_data(cdate)
        limit_info = CLimit(self.dbinfo).get_data(cdate)
        if stock_info.empty or limit_info.empty:
            self.logger.error("info is empty failed")
            return False

        limit_up_list = limit_info[(limit_info.pchange > 0) & (limit_info.prange != 0)].reset_index(drop = True).code.tolist()
        limit_down_list = limit_info[limit_info.pchange < 0].reset_index(drop = True).code.tolist()
        limit_up_list.extend(limit_down_list)
        total = 0

        for _index, pchange in stock_info.pchange.iteritems():
            code = stock_info.loc[_index, 'code']
            if code in limit_up_list: 
                total += 2 * pchange
            else:
                total += pchange

        aver = total / len(stock_info)
        data = {'date':[cdate], 'score':[aver]}

        df = pd.DataFrame.from_dict(data)
        return self.mysql_client.set(df, self.emotion_table)