コード例 #1
0
 def __init__(self, dbinfo=ct.DB_INFO, redis_host=None):
     self.dbinfo = dbinfo
     self.logger = getLogger(__name__)
     self.index_objs = dict()
     self.stock_objs = dict()
     self.updating_date = None
     self.combination_objs = dict()
     self.cal_client = CCalendar(dbinfo, redis_host)
     self.index_info_client = IndexInfo()
     self.cvaluation_client = CValuation()
     self.reviewer = CReivew(dbinfo, redis_host)
     self.comb_info_client = CombinationInfo(dbinfo, redis_host)
     self.stock_info_client = CStockInfo(dbinfo, redis_host)
     self.rindex_stock_data_client = RIndexStock(dbinfo, redis_host)
     self.industry_info_client = IndustryInfo(dbinfo, redis_host)
     self.rindustry_info_client = RIndexIndustryInfo(dbinfo, redis_host)
     self.animation_client = CAnimation(dbinfo, redis_host)
     self.subscriber = Subscriber()
     self.quote_handler = StockQuoteHandler()
     self.ticker_handler = TickerHandler()
     self.connect_client = StockConnect(market_from=ct.SH_MARKET_SYMBOL,
                                        market_to=ct.HK_MARKET_SYMBOL,
                                        dbinfo=dbinfo,
                                        redis_host=redis_host)
     self.margin_client = Margin(dbinfo=dbinfo, redis_host=redis_host)
     self.emotion_client = Emotion(dbinfo=dbinfo, redis_host=redis_host)
     self.sh_exchange_client = StockExchange(ct.SH_MARKET_SYMBOL)
     self.sz_exchange_client = StockExchange(ct.SZ_MARKET_SYMBOL)
コード例 #2
0
 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")
コード例 #3
0
 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")
コード例 #4
0
ファイル: creview.py プロジェクト: orf53975/smart_deal_tool
 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()
コード例 #5
0
ファイル: oversell.py プロジェクト: tfangz888/smart_deal_tool
 def __init__(self):
     self.ris = RIndexStock(dbinfo=ct.OUT_DB_INFO, redis_host='127.0.0.1')
     self.base_color = '#e6daa6'
     self.fig = plt.figure(facecolor=self.base_color, figsize=(24, 24))
     self.price_ax = plt.subplot2grid((12, 12), (0, 0),
                                      rowspan=6,
                                      colspan=12,
                                      facecolor=self.base_color,
                                      fig=self.fig)
     self.ratio_ax = plt.subplot2grid((12, 12), (6, 0),
                                      rowspan=6,
                                      colspan=12,
                                      facecolor=self.base_color,
                                      sharex=self.price_ax,
                                      fig=self.fig)
コード例 #6
0
def create_marauder_map_figure(mdate):
    df = RIndexStock().get_data(mdate)
    TOOLTIPS = [("code", "@code"), ("(pday, profit)", "(@pday, @profit)")]
    TOOLS = [BoxZoomTool(), ResetTool(), HoverTool(tooltips=TOOLTIPS)]
    p = figure(x_axis_label='时间',
               y_axis_label='强度',
               tools=TOOLS,
               toolbar_location="above",
               title="牛熊比例")
    if df is None or df.empty: return p
    source = ColumnDataSource(df)
    color_mapper = LinearColorMapper(palette="Viridis256",
                                     low=df.profit.min(),
                                     high=df.profit.max())
    p.circle(x='pday',
             y='profit',
             color=transform('profit', color_mapper),
             size=5,
             alpha=0.6,
             source=source)
    color_bar = ColorBar(color_mapper=color_mapper,
                         label_standoff=12,
                         location=(0, 0),
                         title='强度')
    p.add_layout(color_bar, 'right')
    return p
コード例 #7
0
def create_stats_figure(mdate):
    limit_info = CLimit().get_data(mdate)
    stock_info = RIndexStock().get_data(mdate)
    stock_info = stock_info[stock_info.volume > 0]  #get volume > 0 stock list
    stock_info = stock_info.reset_index(drop=True)
    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_list = limit_up_list + limit_down_list
    stock_info = stock_info[~stock_info.code.isin(limit_list)]
    changepercent_list = [9, 7, 5, 3, 1, 0, -1, -3, -5, -7, -9]
    num_list = list()
    name_list = list()
    num_list.append(len(limit_up_list))
    name_list.append("涨停")
    c_length = len(changepercent_list)
    for index in range(c_length):
        pchange = changepercent_list[index]
        if 0 == index:
            num_list.append(len(stock_info[stock_info.pchange > pchange]))
            name_list.append(">%s" % pchange)
        elif c_length - 1 == index:
            num_list.append(len(stock_info[stock_info.pchange < pchange]))
            name_list.append("<%s" % pchange)
        else:
            p_max_change = changepercent_list[index - 1]
            num_list.append(
                len(stock_info[(stock_info.pchange > pchange)
                               & (stock_info.pchange < p_max_change)]))
            name_list.append("%s-%s" % (pchange, p_max_change))
    num_list.append(len(limit_down_list))
    name_list.append("跌停")
    num_list.reverse()
    name_list.reverse()
    source = ColumnDataSource(
        data=dict(names=name_list, values=num_list, colors=Category20_13))
    p = figure(x_range=name_list,
               y_range=(0, max(num_list) + 100),
               title="涨跌幅统计")
    p.vbar(x='names', top='values', width=0.9, color='colors', source=source)
    p.xgrid.grid_line_color = None
    p.add_tools(HoverTool(tooltips=[("涨跌幅", "@names"), ("数量", "@values")]))
    return p
コード例 #8
0
 def __init__(self):
     self.base_color = '#e6daa6'
     self.ris = RIndexStock(dbinfo=ct.OUT_DB_INFO, redis_host='127.0.0.1')
     self.sh_market_client = StockExchange(ct.SH_MARKET_SYMBOL,
                                           dbinfo=ct.OUT_DB_INFO,
                                           redis_host='127.0.0.1')
     self.sz_market_client = StockExchange(ct.SZ_MARKET_SYMBOL,
                                           dbinfo=ct.OUT_DB_INFO,
                                           redis_host='127.0.0.1')
     self.fig = plt.figure(facecolor=self.base_color, figsize=(24, 24))
     self.price_ax = plt.subplot2grid((12, 12), (0, 0),
                                      rowspan=6,
                                      colspan=12,
                                      facecolor=self.base_color,
                                      fig=self.fig)
     self.ratio_ax = plt.subplot2grid((12, 12), (6, 0),
                                      rowspan=6,
                                      colspan=12,
                                      facecolor=self.base_color,
                                      sharex=self.price_ax,
                                      fig=self.fig)
コード例 #9
0
ファイル: oversell.py プロジェクト: tfangz888/smart_deal_tool
class OverSell():
    def __init__(self):
        self.ris = RIndexStock(dbinfo=ct.OUT_DB_INFO, redis_host='127.0.0.1')
        self.base_color = '#e6daa6'
        self.fig = plt.figure(facecolor=self.base_color, figsize=(24, 24))
        self.price_ax = plt.subplot2grid((12, 12), (0, 0),
                                         rowspan=6,
                                         colspan=12,
                                         facecolor=self.base_color,
                                         fig=self.fig)
        self.ratio_ax = plt.subplot2grid((12, 12), (6, 0),
                                         rowspan=6,
                                         colspan=12,
                                         facecolor=self.base_color,
                                         sharex=self.price_ax,
                                         fig=self.fig)

    def get_data(self, start_date, end_date, index_code):
        df = self.ris.get_k_data_in_range(start_date, end_date)
        iobj = CIndex(index_code,
                      dbinfo=ct.OUT_DB_INFO,
                      redis_host='127.0.0.1')
        i_data = iobj.get_k_data_in_range(start_date, end_date)
        i_data['time'] = i_data.index.tolist()
        i_data = i_data[[
            'time', 'open', 'high', 'low', 'close', 'volume', 'amount', 'date'
        ]]
        return df, i_data

    def is_market_oversell(self, start_date, end_date, index_code):
        df, index_data = self.get_data(start_date, end_date, index_code)
        info = self.compute_stock_score(df)

    def get_oversell_stocks(self, df):
        data = df[(np.log(df['close']) - np.log(df['mprice'])) /
                  np.log(0.9) > 1]
        return data.code.tolist()

    def compute_stock_score(self, data):
        code_list = list()
        date_list = list()
        rate_list = list()
        oversell_ratio = 0
        for cdate, df in data.groupby(data.date):
            total_num = len(df)
            oversell_code_list = self.get_oversell_stocks(df)
            oversold_num = len(oversell_code_list)
            oversell_ratio = 100 * oversold_num / total_num
            date_list.append(cdate)
            rate_list.append(oversell_ratio)
            code_list.append(oversell_code_list)
        info = {'date': date_list, 'rate': rate_list, 'code': code_list}
        df = pd.DataFrame(info)
        return df

    def plot(self, start_date, end_date, index_code):
        df, index_data = self.get_data(start_date, end_date, index_code)
        date_tickers = index_data.date.tolist()

        def _format_date(x, pos=None):
            if x < 0 or x > len(date_tickers) - 1: return ''
            return date_tickers[int(x)]

        info = self.compute_stock_score(df)
        candlestick_ohlc(self.price_ax,
                         index_data.values,
                         width=1.0,
                         colorup='r',
                         colordown='g')
        self.ratio_ax.plot(info['date'],
                           info['rate'],
                           'r',
                           label="超跌系数",
                           linewidth=1)
        self.price_ax.xaxis.set_major_locator(mticker.MultipleLocator(20))
        self.price_ax.xaxis.set_major_formatter(
            mticker.FuncFormatter(_format_date))
        plt.show()
コード例 #10
0
 def __init__(self):
     self.ris = RIndexStock()
     self.logger = getLogger(__name__)
コード例 #11
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)
コード例 #12
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)
コード例 #13
0
class DataManager:
    def __init__(self, dbinfo=ct.DB_INFO, redis_host=None):
        self.dbinfo = dbinfo
        self.logger = getLogger(__name__)
        self.index_objs = dict()
        self.stock_objs = dict()
        self.updating_date = None
        self.combination_objs = dict()
        self.cal_client = CCalendar(dbinfo, redis_host)
        self.index_info_client = IndexInfo()
        self.cvaluation_client = CValuation()
        self.reviewer = CReivew(dbinfo, redis_host)
        self.comb_info_client = CombinationInfo(dbinfo, redis_host)
        self.stock_info_client = CStockInfo(dbinfo, redis_host)
        self.rindex_stock_data_client = RIndexStock(dbinfo, redis_host)
        self.industry_info_client = IndustryInfo(dbinfo, redis_host)
        self.rindustry_info_client = RIndexIndustryInfo(dbinfo, redis_host)
        self.animation_client = CAnimation(dbinfo, redis_host)
        self.subscriber = Subscriber()
        self.quote_handler = StockQuoteHandler()
        self.ticker_handler = TickerHandler()
        self.connect_client = StockConnect(market_from=ct.SH_MARKET_SYMBOL,
                                           market_to=ct.HK_MARKET_SYMBOL,
                                           dbinfo=dbinfo,
                                           redis_host=redis_host)
        self.margin_client = Margin(dbinfo=dbinfo, redis_host=redis_host)
        self.emotion_client = Emotion(dbinfo=dbinfo, redis_host=redis_host)
        self.sh_exchange_client = StockExchange(ct.SH_MARKET_SYMBOL)
        self.sz_exchange_client = StockExchange(ct.SZ_MARKET_SYMBOL)

    def is_collecting_time(self):
        now_time = datetime.now()
        _date = now_time.strftime('%Y-%m-%d')
        y, m, d = time.strptime(_date, "%Y-%m-%d")[0:3]
        aft_open_hour, aft_open_minute, aft_open_second = (17, 10, 00)
        aft_open_time = datetime(y, m, d, aft_open_hour, aft_open_minute,
                                 aft_open_second)
        aft_close_hour, aft_close_minute, aft_close_second = (23, 59, 59)
        aft_close_time = datetime(y, m, d, aft_close_hour, aft_close_minute,
                                  aft_close_second)
        #self.logger.info("collecting now time. open_time:%s < now_time:%s < close_time:%s" % (aft_open_time, now_time, aft_close_time))
        return aft_open_time < now_time < aft_close_time

    def is_morning_time(self, now_time=datetime.now()):
        _date = now_time.strftime('%Y-%m-%d')
        y, m, d = time.strptime(_date, "%Y-%m-%d")[0:3]
        mor_open_hour, mor_open_minute, mor_open_second = (0, 0, 0)
        mor_open_time = datetime(y, m, d, mor_open_hour, mor_open_minute,
                                 mor_open_second)
        mor_close_hour, mor_close_minute, mor_close_second = (6, 30, 0)
        mor_close_time = datetime(y, m, d, mor_close_hour, mor_close_minute,
                                  mor_close_second)
        return mor_open_time < now_time < mor_close_time

    def collect_combination_runtime_data(self):
        def _combination_run(code_id):
            self.combination_objs[code_id].run()
            return (code_id, True)

        todo_iplist = list(self.combination_objs.keys())
        return concurrent_run(_combination_run, todo_iplist, num=10)

    def collect_stock_runtime_data(self):
        if self.ticker_handler.empty(): return
        datas = self.ticker_handler.getQueue()
        while not datas.empty():
            df = datas.get()
            df = df.set_index('time')
            df.index = pd.to_datetime(df.index)
            for code_str in set(df.code):
                code_id = code_str.split('.')[1]
                self.stock_objs[code_id].run(df.loc[df.code == code_str])

    def init_real_stock_info(self):
        concerned_list = self.comb_info_client.get_concerned_list()
        prefix_concerned_list = [add_prifix(code) for code in concerned_list]
        ret = self.subscriber.subscribe(prefix_concerned_list, SubType.TICKER,
                                        self.ticker_handler)
        if 0 == ret:
            for code in concerned_list:
                if code not in self.stock_objs:
                    self.stock_objs[code] = CStock(code,
                                                   self.dbinfo,
                                                   should_create_influxdb=True,
                                                   should_create_mysqldb=True)
        return ret

    def init_index_info(self):
        index_list = ct.INDEX_DICT.keys()
        prefix_index_list = [add_index_prefix(code) for code in index_list]
        ret = self.subscriber.subscribe(prefix_index_list, SubType.QUOTE,
                                        self.quote_handler)
        if 0 != ret:
            self.logger.error("subscribe for index list failed")
            return ret
        for code in index_list:
            if code not in self.index_objs:
                self.index_objs[code] = CIndex(code,
                                               should_create_influxdb=True,
                                               should_create_mysqldb=True)
        return 0

    def collect_index_runtime_data(self):
        if self.quote_handler.empty(): return
        datas = self.quote_handler.getQueue()
        while not datas.empty():
            df = datas.get()
            df['time'] = df.data_date + ' ' + df.data_time
            df = df.drop(['data_date', 'data_time'], axis=1)
            df = df.set_index('time')
            df.index = pd.to_datetime(df.index)
            for code_str in set(df.code):
                code_id = code_str.split('.')[1]
                self.index_objs[code_id].run(df.loc[df.code == code_str])

    def run(self, sleep_time):
        while True:
            try:
                self.logger.debug("enter run")
                if self.cal_client.is_trading_day():
                    if is_trading_time():
                        t_sleep_time = 1
                        if not self.subscriber.status():
                            self.subscriber.start()
                            if 0 == self.init_index_info(
                            ) and 0 == self.init_real_stock_info():
                                self.init_combination_info()
                            else:
                                self.logger.debug("enter stop subscriber")
                                self.subscriber.stop()
                        else:
                            self.collect_stock_runtime_data()
                            self.collect_combination_runtime_data()
                            self.collect_index_runtime_data()
                            self.animation_client.collect()
                    else:
                        t_sleep_time = sleep_time
                        if self.subscriber.status():
                            self.subscriber.stop()
                else:
                    t_sleep_time = sleep_time
            except Exception as e:
                #traceback.print_exc()
                self.logger.error(e)
            gevent.sleep(t_sleep_time)

    def set_update_info(self,
                        step_length,
                        exec_date,
                        cdate=None,
                        filename=ct.STEPFILE):
        step_info = dict()
        if cdate is None: cdate = 'none'
        step_info[cdate] = dict()
        step_info[cdate]['step'] = step_length
        step_info[cdate]['date'] = exec_date
        with open(filename, 'w') as f:
            json.dump(step_info, f)
        self.logger.info("finish step :%s" % step_length)

    def get_update_info(self,
                        cdate=None,
                        exec_date=None,
                        filename=ct.STEPFILE):
        if cdate is None: cdate = 'none'
        if not os.path.exists(filename): return (0, exec_date)
        with open(filename, 'r') as f:
            step_info = json.load(f)
        if cdate not in step_info: return (0, exec_date)
        return (step_info[cdate]['step'], step_info[cdate]['date'])

    def bootstrap(self,
                  cdate=None,
                  exec_date=datetime.now().strftime('%Y-%m-%d'),
                  ndays=3):
        finished_step, exec_date = self.get_update_info(cdate, exec_date)
        self.logger.info("enter updating.%s" % finished_step)
        if finished_step < 1:
            if not self.cal_client.init():
                self.logger.error("cal client init failed")
                return False
            self.set_update_info(1, exec_date, cdate)

        if finished_step < 2:
            if not self.index_info_client.update():
                self.logger.error("index info init failed")
                return False
            self.set_update_info(2, exec_date, cdate)

        if finished_step < 3:
            if not self.stock_info_client.update():
                self.logger.error("stock info init failed")
                return False
            self.set_update_info(3, exec_date, cdate)

        if finished_step < 4:
            if not self.comb_info_client.update():
                self.logger.error("comb info init failed")
                return False
            self.set_update_info(4, exec_date, cdate)

        if finished_step < 5:
            if not self.industry_info_client.update():
                self.logger.error("industry info init failed")
                return False
            self.set_update_info(5, exec_date, cdate)

        if finished_step < 6:
            if not self.init_tdx_index_info(cdate):
                self.logger.error("init tdx index info failed")
                return False
            self.set_update_info(6, exec_date, cdate)

        if finished_step < 7:
            if not self.sh_exchange_client.update(exec_date, num=ndays):
                self.logger.error("sh exchange update failed")
                return False
            self.set_update_info(7, exec_date, cdate)

        if finished_step < 8:
            if not self.sz_exchange_client.update(exec_date, num=ndays):
                self.logger.error("sz exchange update failed")
                return False
            self.set_update_info(8, exec_date, cdate)

        if finished_step < 9:
            if not self.init_index_components_info(exec_date):
                self.logger.error("init index components info failed")
                return False
            self.set_update_info(9, exec_date, cdate)

        if finished_step < 10:
            if not self.init_industry_info(cdate):
                self.logger.error("init industry info failed")
                return False
            self.set_update_info(10, exec_date, cdate)

        if finished_step < 11:
            if not self.rindustry_info_client.update(exec_date, num=ndays):
                self.logger.error("init %s rindustry info failed" % exec_date)
                return False
            self.set_update_info(11, exec_date, cdate)

        if finished_step < 12:
            if not self.init_yesterday_hk_info(exec_date, num=ndays):
                self.logger.error("init yesterday hk info failed")
                return False
            self.set_update_info(12, exec_date, cdate)

        if finished_step < 13:
            if not self.margin_client.update(exec_date, num=ndays):
                self.logger.error("init yesterday margin failed")
                return False
            self.set_update_info(13, exec_date, cdate)

        if finished_step < 14:
            if not self.init_stock_info(cdate):
                self.logger.error("init stock info set failed")
                return False
            self.set_update_info(14, exec_date, cdate)

        if finished_step < 15:
            if not self.init_base_float_profit():
                self.logger.error("init base float profit for all stock")
                return False
            self.set_update_info(15, exec_date, cdate)

        if finished_step < 16:
            if not self.init_valuation_info(cdate):
                self.logger.error("init stock valuation info failed")
                return False
            self.set_update_info(16, exec_date, cdate)

        if finished_step < 17:
            if not self.init_rvaluation_info(cdate):
                self.logger.error("init r stock valuation info failed")
                return False
            self.set_update_info(17, exec_date, cdate)

        if finished_step < 18:
            if not self.init_rindex_valuation_info(cdate):
                self.logger.error("init r index valuation info failed")
                return False
            self.set_update_info(18, exec_date, cdate)

        if finished_step < 19:
            if not self.rindex_stock_data_client.update(exec_date, num=ndays):
                self.logger.error("rstock data set failed")
                return False
            self.set_update_info(19, exec_date, cdate)

        if finished_step < 20:
            if not self.set_bull_stock_ratio(exec_date, num=ndays):
                self.logger.error("bull ratio set failed")
                return False
            self.set_update_info(20, exec_date, cdate)

        self.logger.info("updating succeed")
        return True

    def clear_network_env(self):
        kill_process("google-chrome")
        kill_process("renderer")
        kill_process("Xvfb")
        kill_process("zygote")
        kill_process("defunct")
        kill_process("show-component-extension-options")

    def update(self, sleep_time):
        succeed = False
        while True:
            self.logger.debug("enter daily update process. %s" %
                              datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            try:
                if self.cal_client.is_trading_day():
                    #self.logger.info("is trading day. %s, succeed:%s" % (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), succeed))
                    if self.is_collecting_time():
                        self.logger.debug(
                            "enter collecting time. %s, succeed:%s" %
                            (datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                             succeed))
                        if not succeed:
                            self.clear_network_env()
                            mdate = datetime.now().strftime('%Y-%m-%d')
                            ndate = get_latest_data_date()
                            if ndate is not None:
                                if ndate >= transfer_date_string_to_int(mdate):
                                    if self.updating_date is None:
                                        self.updating_date = mdate
                                    succeed = self.bootstrap(
                                        cdate=self.updating_date,
                                        exec_date=self.updating_date)
                                    if succeed: self.updating_date = None
                                else:
                                    self.logger.debug("%s is older for %s" %
                                                      (ndate, mdate))
                    else:
                        succeed = False
                gevent.sleep(sleep_time)
            except Exception as e:
                time.sleep(1)
                self.logger.error(e)

    def init_combination_info(self):
        trading_info = self.comb_info_client.get()
        for _, code_id in trading_info['code'].iteritems():
            if str(code_id) not in self.combination_objs:
                self.combination_objs[str(code_id)] = Combination(
                    code_id, self.dbinfo)

    def init_base_float_profit(self):
        def _set_base_float_profit(code_id):
            if CStock(code_id).set_base_floating_profit():
                self.logger.info("%s set base float profit success" % code_id)
                return (code_id, True)
            else:
                self.logger.error("%s set base float profit failed" % code_id)
                return (code_id, False)

        df = self.stock_info_client.get()
        if df.empty: return False
        failed_list = df.code.tolist()
        return process_concurrent_run(_set_base_float_profit,
                                      failed_list,
                                      num=8)

    def init_rindex_valuation_info(self, cdate):
        for code in ct.INDEX_DICT:
            if not self.cvaluation_client.set_index_valuation(code, cdate):
                self.logger.error(
                    "{} set {} data for rvaluation failed".format(code, mdate))
                return False
        return True

    def init_rvaluation_info(self, cdate=None):
        def cget(mdate, code):
            return code, CStock(code).get_val_data(mdate)

        df = self.stock_info_client.get()
        code_list = df.code.tolist()
        try:
            obj_pool = Pool(5000)
            all_df = pd.DataFrame()
            cfunc = partial(cget, cdate)
            for code_data in obj_pool.imap_unordered(cfunc, code_list):
                if code_data[1] is not None and not code_data[1].empty:
                    tem_df = code_data[1]
                    tem_df['code'] = code_data[0]
                    all_df = all_df.append(tem_df)
            obj_pool.join(timeout=5)
            obj_pool.kill()
            all_df = all_df.reset_index(drop=True)
            file_name = "{}.csv".format(cdate)
            file_path = Path(ct.RVALUATION_DIR) / file_name
            all_df.to_csv(file_path,
                          index=False,
                          header=True,
                          mode='w',
                          encoding='utf8')
            return True
        except Exception as e:
            self.logger.error(e)
            return False

    def init_valuation_info(self, cdate=None):
        df = self.stock_info_client.get()
        code_list = df['code'].tolist()
        time2market_list = df['timeToMarket'].tolist()
        code2timedict = dict(zip(code_list, time2market_list))
        cfun = partial(self.cvaluation_client.set_stock_valuation,
                       code2timedict, cdate)
        return process_concurrent_run(cfun,
                                      code_list,
                                      num=15,
                                      black_list=list())

    def init_stock_info(self, cdate=None):
        def _set_stock_info(mdate, bonus_info, index_info, code_id):
            try:
                if CStock(code_id).set_k_data(bonus_info, index_info, mdate):
                    self.logger.info("%s set k data success for date:%s",
                                     code_id, mdate)
                    return (code_id, True)
                else:
                    self.logger.error("%s set k data failed for date:%s",
                                      code_id, mdate)
                    return (code_id, False)
            except Exception as e:
                self.logger.error("%s set k data for date %s exception:%s",
                                  code_id, mdate, e)
                return (code_id, False)

        #get stock bonus info
        bonus_info = pd.read_csv("/data/tdx/base/bonus.csv",
                                 sep=',',
                                 dtype={
                                     'code': str,
                                     'market': int,
                                     'type': int,
                                     'money': float,
                                     'price': float,
                                     'count': float,
                                     'rate': float,
                                     'date': int
                                 })

        index_info = CIndex('000001').get_k_data()
        if index_info is None or index_info.empty: return False
        df = self.stock_info_client.get()
        if df.empty: return False
        failed_list = df.code.tolist()
        if cdate is None:
            cfunc = partial(_set_stock_info, cdate, bonus_info, index_info)
            return process_concurrent_run(cfunc, failed_list, num=8)
        else:
            cfunc = partial(_set_stock_info, cdate, bonus_info, index_info)
            succeed = True
            if not process_concurrent_run(cfunc, failed_list, num=8):
                succeed = False
            return succeed
            #start_date = get_day_nday_ago(cdate, num = 4, dformat = "%Y-%m-%d")
            #for mdate in get_dates_array(start_date, cdate, asending = True):
            #    if self.cal_client.is_trading_day(mdate):
            #        self.logger.info("start recording stock info: %s", mdate)
            #        cfunc = partial(_set_stock_info, mdate, bonus_info, index_info)
            #        if not process_concurrent_run(cfunc, failed_list, num = 500):
            #            self.logger.error("compute stock info for %s failed", mdate)
            #            return False
            #return True

    def init_industry_info(self, cdate, num=1):
        def _set_industry_info(cdate, code_id):
            return (code_id, CIndex(code_id).set_k_data(cdate))

        df = self.industry_info_client.get()
        if cdate is None:
            cfunc = partial(_set_industry_info, cdate)
            return concurrent_run(cfunc, df.code.tolist(), num=5)
        else:
            succeed = True
            start_date = get_day_nday_ago(cdate, num=num, dformat="%Y-%m-%d")
            for mdate in get_dates_array(start_date, cdate, asending=True):
                if self.cal_client.is_trading_day(mdate):
                    cfunc = partial(_set_industry_info, mdate)
                    if not concurrent_run(cfunc, df.code.tolist(), num=5):
                        succeed = False
            return succeed

    def init_yesterday_hk_info(self, cdate, num):
        succeed = True
        for data in ((ct.SH_MARKET_SYMBOL, ct.HK_MARKET_SYMBOL),
                     (ct.SZ_MARKET_SYMBOL, ct.HK_MARKET_SYMBOL)):
            if not self.connect_client.set_market(data[0], data[1]):
                self.logger.error("connect_client for %s failed" % data)
                succeed = False
                continue
            if not self.connect_client.update(cdate, num=num):
                succeed = False

            self.connect_client.close()
            self.connect_client.quit()
        return succeed

    def get_concerned_index_codes(self):
        index_codes = list(ct.INDEX_DICT.keys())
        #添加MSCI板块
        index_codes.append('880883')
        return index_codes

    def init_index_components_info(self, cdate=None):
        if cdate is None: cdate = datetime.now().strftime('%Y-%m-%d')

        def _set_index_info(code_id):
            if code_id in self.index_objs:
                _obj = self.index_objs[code_id]
            else:
                _obj = CIndex(code_id) if code_id in list(
                    ct.INDEX_DICT.keys()) else TdxFgIndex(code_id)
            return (code_id, _obj.set_components_data(cdate))

        index_codes = self.get_concerned_index_codes()
        return concurrent_run(_set_index_info, index_codes, num=10)

    def set_bull_stock_ratio(self, cdate, num=10):
        def _set_bull_stock_ratio(code_id):
            return (code_id, BullStockRatio(code_id).update(cdate, num))

        index_codes = self.get_concerned_index_codes()
        return concurrent_run(_set_bull_stock_ratio, index_codes)

    def init_tdx_index_info(self, cdate=None, num=1):
        def _set_index_info(cdate, code_id):
            try:
                if code_id in self.index_objs:
                    _obj = self.index_objs[code_id]
                else:
                    _obj = CIndex(code_id) if code_id in list(
                        ct.TDX_INDEX_DICT.keys()) else TdxFgIndex(code_id)
                return (code_id, _obj.set_k_data(cdate))
            except Exception as e:
                self.logger.error(e)
                return (code_id, False)

        #index_code_list = self.get_concerned_index_codes()
        index_code_list = list(ct.TDX_INDEX_DICT.keys())
        if cdate is None:
            cfunc = partial(_set_index_info, cdate)
            return concurrent_run(cfunc, index_code_list, num=5)
        else:
            succeed = True
            start_date = get_day_nday_ago(cdate, num=num, dformat="%Y-%m-%d")
            for mdate in get_dates_array(start_date, cdate, asending=True):
                if self.cal_client.is_trading_day(mdate):
                    cfunc = partial(_set_index_info, mdate)
                    if not concurrent_run(cfunc, index_code_list, num=5):
                        succeed = False
            return succeed
コード例 #14
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)
コード例 #15
0
ファイル: cmodel.py プロジェクト: orf53975/smart_deal_tool
    sh_df = get_market_data(ct.SH_MARKET_SYMBOL, start_date, end_date)
    sz_df = 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)]
    sz_df = sz_df[sz_df.date.isin(date_list)]
    #rzrq info
    sh_rzrq_df = get_rzrq_info(ct.SH_MARKET_SYMBOL, start_date, end_date)
    sz_rzrq_df = 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)]
    sz_rzrq_df = sz_rzrq_df[sz_rzrq_df.date.isin(date_list)]
    #average price info
    av_df = get_index_df('880003', start_date, end_date)
    #limit up and down info
    limit_info = CLimit().get_data(cdate)
    stock_info = RIndexStock().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 = get_index_data(end_date)
    #industry analysis
    industry_info = get_industry_data(cdate)
    #all stock info 
    all_stock_info = RIndexStock().get_k_data_in_range(start_date, end_date)
   
    stm = StrongerThanMarketSelecter()
    stm_code_list = stm.choose(all_stock_info, av_df)

    amus = AntiMarketUpSelecter()
    amus_code_list = amus.choose(stock_info)
コード例 #16
0
import os
import sys
from os.path import abspath, dirname

sys.path.insert(0, dirname(dirname(dirname(abspath(__file__)))))
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'):
コード例 #17
0
 def __init__(self, code_list):
     self.codes = code_list
     self.ris = RIndexStock()
     self.logger = getLogger(__name__)
コード例 #18
0
 def __init__(self, dinfo, rhost):
     self.dbinfo = dinfo
     self.redis_host = rhost
     self.base_color = '#e6daa6'
     self.ris = RIndexStock(dbinfo=self.dbinfo, redis_host=self.redis_host)
コード例 #19
0
        return 1
    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
コード例 #20
0
def get_stock_data(start_date, end_date):
    ris = RIndexStock(ct.OUT_DB_INFO, redis_host='127.0.0.1')
    return ris.get_k_data_in_range(start_date, end_date)
コード例 #21
0
ファイル: creview.py プロジェクト: orf53975/smart_deal_tool
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)
コード例 #22
0
class DataManager:
    def __init__(self, dbinfo=ct.DB_INFO, redis_host=None):
        self.dbinfo = dbinfo
        self.logger = getLogger(__name__)
        self.index_objs = dict()
        self.stock_objs = dict()
        self.combination_objs = dict()
        self.cal_client = CCalendar(dbinfo, redis_host)
        self.index_info_client = IndexInfo()
        self.comb_info_client = CombinationInfo(dbinfo, redis_host)
        self.stock_info_client = CStockInfo(dbinfo, redis_host)
        self.rindex_stock_data_client = RIndexStock(dbinfo, redis_host)
        self.industry_info_client = IndustryInfo(dbinfo, redis_host)
        self.rindustry_info_client = RIndexIndustryInfo(dbinfo, redis_host)
        self.limit_client = CLimit(dbinfo, redis_host)
        self.animation_client = CAnimation(dbinfo, redis_host)
        self.subscriber = Subscriber()
        self.quote_handler = StockQuoteHandler()
        self.ticker_handler = TickerHandler()
        self.connect_client = StockConnect(market_from=ct.SH_MARKET_SYMBOL,
                                           market_to=ct.HK_MARKET_SYMBOL,
                                           dbinfo=dbinfo,
                                           redis_host=redis_host)
        self.margin_client = Margin(dbinfo=dbinfo, redis_host=redis_host)
        self.emotion_client = Emotion(dbinfo=dbinfo, redis_host=redis_host)
        self.sh_exchange_client = StockExchange(ct.SH_MARKET_SYMBOL)
        self.sz_exchange_client = StockExchange(ct.SZ_MARKET_SYMBOL)

    def is_collecting_time(self, now_time=datetime.now()):
        _date = now_time.strftime('%Y-%m-%d')
        y, m, d = time.strptime(_date, "%Y-%m-%d")[0:3]
        aft_open_hour, aft_open_minute, aft_open_second = (19, 00, 00)
        aft_open_time = datetime(y, m, d, aft_open_hour, aft_open_minute,
                                 aft_open_second)
        aft_close_hour, aft_close_minute, aft_close_second = (23, 59, 59)
        aft_close_time = datetime(y, m, d, aft_close_hour, aft_close_minute,
                                  aft_close_second)
        return aft_open_time < now_time < aft_close_time

    def is_morning_time(self, now_time=datetime.now()):
        _date = now_time.strftime('%Y-%m-%d')
        y, m, d = time.strptime(_date, "%Y-%m-%d")[0:3]
        mor_open_hour, mor_open_minute, mor_open_second = (0, 0, 0)
        mor_open_time = datetime(y, m, d, mor_open_hour, mor_open_minute,
                                 mor_open_second)
        mor_close_hour, mor_close_minute, mor_close_second = (6, 30, 0)
        mor_close_time = datetime(y, m, d, mor_close_hour, mor_close_minute,
                                  mor_close_second)
        return mor_open_time < now_time < mor_close_time

    def collect_combination_runtime_data(self):
        def _combination_run(code_id):
            self.combination_objs[code_id].run()
            return (code_id, True)

        todo_iplist = list(self.combination_objs.keys())
        return concurrent_run(_combination_run, todo_iplist, num=10)

    def collect_stock_runtime_data(self):
        if self.ticker_handler.empty(): return
        datas = self.ticker_handler.getQueue()
        while not datas.empty():
            df = datas.get()
            df = df.set_index('time')
            df.index = pd.to_datetime(df.index)
            for code_str in set(df.code):
                code_id = code_str.split('.')[1]
                self.stock_objs[code_id].run(df.loc[df.code == code_str])

    def init_real_stock_info(self):
        concerned_list = self.comb_info_client.get_concerned_list()
        prefix_concerned_list = [add_prifix(code) for code in concerned_list]
        ret = self.subscriber.subscribe(prefix_concerned_list, SubType.TICKER,
                                        self.ticker_handler)
        if 0 == ret:
            for code in concerned_list:
                if code not in self.stock_objs:
                    self.stock_objs[code] = CStock(code,
                                                   self.dbinfo,
                                                   should_create_influxdb=True,
                                                   should_create_mysqldb=True)
        return ret

    def init_index_info(self):
        index_list = ct.INDEX_DICT.keys()
        prefix_index_list = [add_index_prefix(code) for code in index_list]
        ret = self.subscriber.subscribe(prefix_index_list, SubType.QUOTE,
                                        self.quote_handler)
        if 0 != ret:
            self.logger.error("subscribe for index list failed")
            return ret
        for code in index_list:
            if code not in self.index_objs:
                self.index_objs[code] = CIndex(code,
                                               should_create_influxdb=True,
                                               should_create_mysqldb=True)

    def collect_index_runtime_data(self):
        if self.quote_handler.empty(): return
        datas = self.quote_handler.getQueue()
        while not datas.empty():
            df = datas.get()
            df['time'] = df.data_date + ' ' + df.data_time
            df = df.drop(['data_date', 'data_time'], axis=1)
            df = df.set_index('time')
            df.index = pd.to_datetime(df.index)
            for code_str in set(df.code):
                code_id = code_str.split('.')[1]
                self.index_objs[code_id].run(df.loc[df.code == code_str])

    def run(self, sleep_time):
        while True:
            try:
                if self.cal_client.is_trading_day():
                    if is_trading_time():
                        sleep_time = 1
                        if not self.subscriber.status():
                            self.subscriber.start()
                            if 0 == self.init_index_info(
                            ) and 0 == self.init_real_stock_info():
                                self.init_combination_info()
                            else:
                                self.logger.debug("enter stop dict time")
                                self.subscriber.stop()
                        else:
                            self.collect_stock_runtime_data()
                            self.collect_combination_runtime_data()
                            self.collect_index_runtime_data()
                            self.animation_client.collect()
                    else:
                        sleep_time = 60
                        if self.subscriber.status():
                            self.subscriber.stop()
            except Exception as e:
                traceback.print_exc()
                self.logger.error(e)
            time.sleep(sleep_time)

    def set_update_info(self,
                        step_length,
                        exec_date,
                        cdate=None,
                        filename=ct.STEPFILE):
        step_info = dict()
        if cdate is None: cdate = 'none'
        step_info[cdate] = dict()
        step_info[cdate]['step'] = step_length
        step_info[cdate]['date'] = exec_date
        with open(filename, 'w') as f:
            json.dump(step_info, f)
        self.logger.info("finish step :%s" % step_length)

    def get_update_info(self,
                        cdate=None,
                        exec_date=None,
                        filename=ct.STEPFILE):
        if cdate is None: cdate = 'none'
        if not os.path.exists(filename): return (0, exec_date)
        with open(filename, 'r') as f:
            step_info = json.load(f)
        if cdate not in step_info: return (0, exec_date)
        return (step_info[cdate]['step'], step_info[cdate]['date'])

    def bootstrap(self,
                  cdate=None,
                  exec_date=datetime.now().strftime('%Y-%m-%d')):
        finished_step, exec_date = self.get_update_info(cdate, exec_date)
        self.logger.info("enter updating.%s" % finished_step)
        if finished_step < 1:
            if not self.cal_client.init():
                self.logger.error("cal_client init failed")
                return False
            self.set_update_info(1, exec_date, cdate)

        if finished_step < 2:
            if not self.index_info_client.update():
                self.logger.error("index_info init failed")
                return False
            self.set_update_info(2, exec_date, cdate)

        if finished_step < 3:
            if not self.stock_info_client.update():
                self.logger.error("stock_info init failed")
                return False
            self.set_update_info(3, exec_date, cdate)

        if finished_step < 4:
            if not self.comb_info_client.update():
                self.logger.error("comb_info init failed")
                return False
            self.set_update_info(4, exec_date, cdate)

        if finished_step < 5:
            if not self.industry_info_client.update():
                self.logger.error("industry_info init failed")
                return False
            self.set_update_info(5, exec_date, cdate)

        if finished_step < 6:
            if not self.download_and_extract(exec_date):
                self.logger.error("download_and_extract failed")
                return False
            self.set_update_info(6, exec_date, cdate)

        if finished_step < 7:
            if not self.init_tdx_index_info(cdate):
                self.logger.error("init_tdx_index_info failed")
                return False
            self.set_update_info(7, exec_date, cdate)

        if finished_step < 8:
            if not self.sh_exchange_client.update(exec_date, num=30):
                self.logger.error("sh exchange update failed")
                return False
            self.set_update_info(8, exec_date, cdate)

        if finished_step < 9:
            if not self.sz_exchange_client.update(exec_date, num=30):
                self.logger.error("sz exchange update failed")
                return False
            self.set_update_info(9, exec_date, cdate)

        if finished_step < 10:
            if not self.init_index_components_info(exec_date):
                self.logger.error("init index components info failed")
                return False
            self.set_update_info(10, exec_date, cdate)

        if finished_step < 11:
            if not self.init_industry_info(cdate):
                self.logger.error("init_industry_info failed")
                return False
            self.set_update_info(11, exec_date, cdate)

        if finished_step < 12:
            if not self.rindustry_info_client.update(exec_date):
                self.logger.error("init %s rindustry info failed" % exec_date)
                return False
            self.set_update_info(12, exec_date, cdate)

        if finished_step < 13:
            if not self.limit_client.update(exec_date):
                self.logger.error("init_limit_info failed")
                return False
            self.set_update_info(13, exec_date, cdate)

        if finished_step < 14:
            if not self.init_yesterday_hk_info(exec_date):
                self.logger.error("init_yesterday_hk_info failed")
                return False
            self.set_update_info(14, exec_date, cdate)

        if finished_step < 15:
            if not self.margin_client.update(exec_date):
                self.logger.error("init_yesterday_margin failed")
                return False
            self.set_update_info(15, exec_date, cdate)

        if finished_step < 16:
            if not self.init_stock_info(cdate):
                self.logger.error("init_stock_info set failed")
                return False
            self.set_update_info(16, exec_date, cdate)

        if finished_step < 17:
            if not self.init_base_float_profit():
                self.logger.error("init base float profit for all stock")
                return False
            self.set_update_info(17, exec_date, cdate)

        if finished_step < 18:
            if not self.rindex_stock_data_client.update(exec_date, num=300):
                self.logger.error("rindex_stock_data set failed")
                return False
            self.set_update_info(18, exec_date, cdate)

        self.logger.info("updating succeed")
        return True

    def update(self, sleep_time):
        while True:
            self.logger.info("enter daily update process. %s" %
                             datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
            try:
                if self.cal_client.is_trading_day():
                    self.logger.info(
                        "is trading day. %s" %
                        datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
                    if self.is_collecting_time():
                        self.logger.info(
                            "is collecting time. %s" %
                            datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
                        self.bootstrap(
                            cdate=datetime.now().strftime('%Y-%m-%d'))
            except Exception as e:
                kill_process("google-chrome")
                kill_process("renderer")
                kill_process("Xvfb")
                kill_process("zygote")
                kill_process("defunct")
                kill_process("show-component-extension-options")
                self.logger.error(e)
            time.sleep(sleep_time)

    def init_combination_info(self):
        trading_info = self.comb_info_client.get()
        for _, code_id in trading_info['code'].iteritems():
            if str(code_id) not in self.combination_objs:
                self.combination_objs[str(code_id)] = Combination(
                    code_id, self.dbinfo)

    def init_base_float_profit(self):
        def _set_base_float_profit(code_id):
            return (code_id,
                    True) if CStock(code_id).set_base_floating_profit() else (
                        code_id, False)

        failed_list = self.stock_info_client.get().code.tolist()
        return process_concurrent_run(_set_base_float_profit,
                                      failed_list,
                                      num=500)

    def init_stock_info(self, cdate=None):
        def _set_stock_info(_date, bonus_info, index_info, code_id):
            try:
                if CStock(code_id).set_k_data(bonus_info, index_info, _date):
                    self.logger.info("%s set k data success" % code_id)
                    return (code_id, True)
                else:
                    self.logger.error("%s set k data failed" % code_id)
                    return (code_id, False)
            except Exception as e:
                self.logger.error("%s set k data exception:%s" % (code_id, e))
                return (code_id, False)

        #get stock bonus info
        bonus_info = pd.read_csv("/data/tdx/base/bonus.csv",
                                 sep=',',
                                 dtype={
                                     'code': str,
                                     'market': int,
                                     'type': int,
                                     'money': float,
                                     'price': float,
                                     'count': float,
                                     'rate': float,
                                     'date': int
                                 })

        index_info = CIndex('000001').get_k_data()
        if index_info is None or index_info.empty: return False

        df = self.stock_info_client.get()
        failed_list = df.code.tolist()
        if cdate is None:
            cfunc = partial(_set_stock_info, cdate, bonus_info, index_info)
            return process_concurrent_run(cfunc, failed_list, num=5)
        else:
            succeed = True
            start_date = get_day_nday_ago(cdate, num=10, dformat="%Y-%m-%d")
            for mdate in get_dates_array(start_date, cdate, asending=True):
                if self.cal_client.is_trading_day(mdate):
                    cfunc = partial(_set_stock_info, mdate, bonus_info,
                                    index_info)
                    if not process_concurrent_run(cfunc, failed_list, num=500):
                        succeed = False
            return succeed

    def init_industry_info(self, cdate):
        def _set_industry_info(cdate, code_id):
            return (code_id, CIndex(code_id).set_k_data(cdate))

        df = self.industry_info_client.get()
        if cdate is None:
            cfunc = partial(_set_industry_info, cdate)
            return concurrent_run(cfunc, df.code.tolist(), num=5)
        else:
            succeed = True
            start_date = get_day_nday_ago(cdate, num=30, dformat="%Y-%m-%d")
            for mdate in get_dates_array(start_date, cdate, asending=True):
                if self.cal_client.is_trading_day(mdate):
                    cfunc = partial(_set_industry_info, mdate)
                    if not concurrent_run(cfunc, df.code.tolist(), num=5):
                        succeed = False
            return succeed

    def init_yesterday_hk_info(self, cdate):
        succeed = True
        for data in ((ct.SH_MARKET_SYMBOL, ct.HK_MARKET_SYMBOL),
                     (ct.SZ_MARKET_SYMBOL, ct.HK_MARKET_SYMBOL)):
            if not self.connect_client.set_market(data[0], data[1]):
                self.logger.error("connect_client for %s failed" % data)
                succeed = False
                continue

            if not self.connect_client.update(cdate):
                succeed = False

            self.connect_client.close()
            self.connect_client.quit()
        kill_process("zygote")
        kill_process("defunct")
        kill_process("show-component-extension-options")
        return succeed

    def init_index_components_info(self, cdate=None):
        if cdate is None: cdate = datetime.now().strftime('%Y-%m-%d')

        def _set_index_info(code_id):
            _obj = self.index_objs[
                code_id] if code_id in self.index_objs else CIndex(code_id)
            return (code_id, _obj.set_components_data(cdate))

        return concurrent_run(_set_index_info,
                              list(ct.INDEX_DICT.keys()),
                              num=10)

    def init_tdx_index_info(self, cdate=None):
        def _set_index_info(cdate, code_id):
            try:
                _obj = self.index_objs[
                    code_id] if code_id in self.index_objs else CIndex(code_id)
                return (code_id, _obj.set_k_data(cdate))
            except Exception as e:
                self.logger.error(e)
                return (code_id, False)

        if cdate is None:
            cfunc = partial(_set_index_info, cdate)
            return concurrent_run(cfunc, list(ct.TDX_INDEX_DICT.keys()), num=5)
        else:
            succeed = True
            start_date = get_day_nday_ago(cdate, num=30, dformat="%Y-%m-%d")
            for mdate in get_dates_array(start_date, cdate, asending=True):
                if self.cal_client.is_trading_day(mdate):
                    cfunc = partial(_set_index_info, mdate)
                    if not concurrent_run(
                            cfunc, list(ct.TDX_INDEX_DICT.keys()), num=5):
                        succeed = False
            return succeed

    def download_and_extract(self, cdate):
        try:
            if not download(ct.ZIP_DIR, cdate): return False
            list_files = os.listdir(ct.ZIP_DIR)
            for filename in list_files:
                if not filename.startswith('.'):
                    file_path = os.path.join(ct.ZIP_DIR, filename)
                    if os.path.exists(file_path):
                        unzip(file_path, ct.TIC_DIR)
            return True
        except Exception as e:
            self.logger.error(e)
            return False
コード例 #23
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