示例#1
0
 def set_market(self, market_from, market_to):
     self.market_from = market_from
     self.market_to = market_to
     self.balcklist = [
         "2018-10-17", "2018-09-25", "2018-07-02", "2018-05-22",
         "2018-04-02", "2018-03-30"
     ] if market_from in [ct.SH_MARKET_SYMBOL, ct.SZ_MARKET_SYMBOL
                          ] else list()
     self.dbname = self.get_dbname(market_from, market_to)
     self.crawler = MCrawl(market_from)
     self.mysql_client = CMySQL(self.dbinfo, self.dbname, iredis=self.redis)
     return False if not self.mysql_client.create_db(self.dbname) else True
示例#2
0
class StockConnect(object):
    def __init__(self,
                 market_from=ct.SH_MARKET_SYMBOL,
                 market_to=ct.HK_MARKET_SYMBOL,
                 dbinfo=ct.DB_INFO,
                 redis_host=None):
        self.market_from = market_from
        self.market_to = market_to
        self.balcklist = None
        self.crawler = None
        self.mysql_client = None
        self.dbinfo = dbinfo
        self.logger = getLogger(__name__)
        self.redis = create_redis_obj(
        ) if redis_host is None else create_redis_obj(host=redis_host)

    def set_market(self, market_from, market_to):
        self.market_from = market_from
        self.market_to = market_to
        self.balcklist = [
            "2018-10-17", "2018-09-25", "2018-07-02", "2018-05-22",
            "2018-04-02", "2018-03-30"
        ] if market_from in [ct.SH_MARKET_SYMBOL, ct.SZ_MARKET_SYMBOL
                             ] else list()
        self.dbname = self.get_dbname(market_from, market_to)
        self.crawler = MCrawl(market_from)
        self.mysql_client = CMySQL(self.dbinfo, self.dbname, iredis=self.redis)
        return False if not self.mysql_client.create_db(self.dbname) else True

    def quit(self):
        self.crawler.quit()

    def close(self):
        self.crawler.close()

    @staticmethod
    def get_dbname(mfrom, mto):
        return "%s2%s" % (mfrom, mto)

    def get_table_name(self, cdate):
        cdates = cdate.split('-')
        return "%s_stock_day_%s_%s" % (self.dbname, cdates[0],
                                       (int(cdates[1]) - 1) // 3 + 1)

    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 create_table(self, table):
        sql = 'create table if not exists %s(date varchar(10) not null,\
                                             code varchar(10) not null,\
                                             name varchar(90),\
                                             volume int,\
                                             percent float,\
                                             PRIMARY KEY (date, code))' % table
        return True if table in self.mysql_client.get_all_tables(
        ) else self.mysql_client.create(sql, table)

    def get_k_data_in_range(self, start_date, end_date):
        ndays = delta_days(start_date, end_date)
        date_dmy_format = time.strftime("%m/%d/%Y",
                                        time.strptime(start_date, "%Y-%m-%d"))
        data_times = pd.date_range(date_dmy_format, periods=ndays, freq='D')
        date_only_array = np.vectorize(lambda s: s.strftime('%Y-%m-%d'))(
            data_times.to_pydatetime())
        data_dict = OrderedDict()
        for _date in date_only_array:
            if CCalendar.is_trading_day(_date, redis=self.redis):
                table_name = self.get_table_name(_date)
                if table_name not in data_dict: data_dict[table_name] = list()
                data_dict[table_name].append(str(_date))
        all_df = pd.DataFrame()
        for key in data_dict:
            table_list = sorted(data_dict[key], reverse=False)
            if len(table_list) == 1:
                df = self.get_k_data(table_list[0])
                if df is not None: all_df = all_df.append(df)
            else:
                start_date = table_list[0]
                end_date = table_list[len(table_list) - 1]
                df = self.get_data_between(start_date, end_date)
                if df is not None: all_df = all_df.append(df)
        return all_df

    def get_data_between(self, start_date, end_date):
        #start_date and end_date should be in the same table
        sql = "select * from %s where date between \"%s\" and \"%s\"" % (
            self.get_table_name(start_date), start_date, end_date)
        return self.mysql_client.get(sql)

    def get_k_data(self, cdate=datetime.now().strftime('%Y-%m-%d')):
        sql = "select * from %s where date=\"%s\"" % (
            self.get_table_name(cdate), cdate)
        return self.mysql_client.get(sql)

    def update(self, end_date=None, num=10):
        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 mdate == end_date or mdate in self.balcklist: continue
                if not self.set_data(mdate):
                    succeed = False
        return succeed

    def is_table_exists(self, table_name):
        if self.redis.exists(self.dbname):
            return table_name in set(
                str(table, encoding=ct.UTF8)
                for table in self.redis.smembers(self.dbname))
        return False

    def set_data(self, cdate=datetime.now().strftime('%Y-%m-%d')):
        table_name = self.get_table_name(cdate)
        if not self.is_table_exists(table_name):
            if not self.create_table(table_name):
                self.logger.error("create tick table failed")
                return False
            self.redis.sadd(self.dbname, table_name)

        if self.is_date_exists(table_name, cdate):
            self.logger.debug("existed table:%s, date:%s" %
                              (table_name, cdate))
            return True

        ret, df = self.crawler.crawl(cdate)
        if ret != 0: return False
        if df.empty: return True
        df = df.reset_index(drop=True)
        df['date'] = cdate
        if self.mysql_client.set(df, table_name):
            return self.redis.sadd(table_name, cdate)
        return False