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)
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)
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()
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)