def sendConcernedStkPicToSelf_V2(): """ 将自己关心的数据打印出图,发送到qq 相较于之前版本,本次改进为: 1、使用json文件中的code列表代替数据库中的列表 2、进行判断,出发发送条件再予以发送 :return: """ towho = '影子2' send_qq(towho, '以下是已入的stk的形势图:') code_list = readConfig()['buy_stk'] for x in code_list + ['sh', 'sz', 'cyb']: df = get_k_data_JQ(x, 400) fig, _ = genStkPicForQQ(df) plt.title(str(x)) send_pic_qq(towho, fig) # plt.show() plt.close() fig, _ = genStkIdxPicForQQ(df) plt.title(str(x)) send_pic_qq(towho, fig) # plt.show() plt.close() send_W_M_MACD(x, towho)
def sendConcernedStkPicToSelf_T(): """ 将自己关心的数据打印出图,发送到qq :return: """ towho = '影子2' send_qq(towho, '以下是已入的stk的形势图:') stk_buy = readConfig()['buy_stk'] for x in stk_buy + ['sh', 'sz', 'cyb']: df = get_k_data_JQ(x, 400) fig, _, attention = genStkPicForQQ(df, x) if attention: send_pic_qq(towho, fig) send_W_M_MACD(x, towho) plt.close() # 打印第二张套图 fig, _, attention = genStkIdxPicForQQ(df, x) if attention: send_pic_qq(towho, fig) plt.close()
def updatePotInfo(): """ :param df_H_L_Pot: :return: """ # h_l_pot_info_url = '.\InfoRestore\df_H_L_Pot.pkl' if os.path.exists(h_l_pot_info_url): with open(h_l_pot_info_url, 'rb') as f: try: h_l_pot_info = pickle.load(f) except: h_l_pot_info = pd.DataFrame() else: h_l_pot_info = pd.DataFrame() if h_l_pot_info.empty: h_l_pot_info = initPotInfo(get_h_l_pot(stk_list)) else: new_pot_info = get_h_l_pot(stk_list) h_l_pot_info = pd.concat([ h_l_pot_info.drop([ 'half_year_high', 'half_year_low', 'month_high', 'month_low', 'year_high', 'year_low' ], 1), new_pot_info.drop('stk', 1) ], axis=1) # 将结果序列化 with open(h_l_pot_info_url, 'wb') as f: pickle.dump(h_l_pot_info, f) send_qq(u'影子', '高底线信息更新成功!')
def printConcernedPredict2Self(): win_qq_name = u'影子2' for stk in ['000001', '000333', '300183']: close_today = ts.get_k_data( stk, start=add_date_str(get_current_date_str(), -5)).tail(1)['close'].values[0] r = [(label, '%0.2f' % predict_tomorrow(stk, label, N_STEPS=N_STEPS, feature_cols=feature_cols, HIDDEN_SIZE=HIDDEN_SIZE, NUM_LAYERS=NUM_LAYERS)) for label in ['high', 'low', 'close']] # 增加与今天收盘价的对比 r_contrast = [ (x[0], x[1], '%0.2f' % ((float(x[1]) - close_today) / close_today * 100) + '%') for x in r ] # stk2name = { # 'sh': '上证', # 'sz': '深证', # 'cyb': '创业板' # } send_qq(win_qq_name, stk + ':\n' + str(r_contrast))
def judgeAndSendMsg(): """ 按频率调用, :return: """ if os.path.exists(h_l_pot_info_url): with open(h_l_pot_info_url, 'rb') as f: h_l_pot_info = pickle.load(f) else: print('函数 judgeAndSendMsg: 加载高低信息失败!') return df_H_L_Pot = h_l_pot_info for stk in df_H_L_Pot.index: # 获取该stk的实时价格 current_price = float( ts.get_realtime_quotes(df_H_L_Pot.loc[stk, 'stk'])['price'].values[0]) # 将当前价格保存,用于验证计算准确性 df_H_L_Pot.loc[stk, 'current_price'] = current_price """ 年线判断 """ df_H_L_Pot = lineJudge(df_H_L_Pot_index=stk, current_price=current_price, df_info=df_H_L_Pot, line_str='year') """ ----------------- 半年线判断 -----------------""" df_H_L_Pot = lineJudge(df_H_L_Pot_index=stk, current_price=current_price, df_info=df_H_L_Pot, line_str='half_year') """ ----------------- 月线判断 ----------------""" df_H_L_Pot = lineJudge(df_H_L_Pot_index=stk, current_price=current_price, df_info=df_H_L_Pot, line_str='month') """ 检查并发送消息 """ for idx in df_H_L_Pot.index: # 遍历年线、半年线和月线 for sts in ['year_status', 'half_year_status', 'month_status']: if (df_H_L_Pot.loc[idx, sts] != u'正常') & (df_H_L_Pot.loc[ idx, sts] != df_H_L_Pot.loc[idx, sts + '_last']): send_qq( u'影子', 'stk:' + getNameByStkCode( g_total_stk_info_mysql, df_H_L_Pot.loc[idx, 'stk']) + '\n' + '当前价格:' + str(df_H_L_Pot.loc[idx, 'current_price']) + '\n' + '事件: “' + df_H_L_Pot.loc[idx, sts + '_last'] + '” --> “' + df_H_L_Pot.loc[idx, sts] + '”' + '\n\n') df_H_L_Pot.loc[idx, sts + '_last'] = df_H_L_Pot.loc[idx, sts] with open(h_l_pot_info_url, 'wb') as f: pickle.dump(h_l_pot_info, f) print('函数 judgeAndSendMsg: 完成本次判断!')
def printMainRank(): """ 打印重要的index """ r = [(x, '%.2f' % (calRealtimeRankWithGlobal(stk_code=x)[0])) for x in ['sh', 'sz', 'cyb']] send_qq('影子', "Main_Index:\n" + str(r))
def printConcernedStkM305(): for stk in stk_list: try: sendM305Pic('影子', 'cyb') except: send_qq('影子', '打印' + stk + '的M305趋势图失败!')
def updateConcernStkMData(): """ 定时器定时调用,更新各stk的M离心度历史数据 :return: """ for stk in stk_list: saveStkMRankHistoryData2Global(stk_code=stk, history_days=400, m_days=9, save_dir=SeaSelectDataPWD+'/stk_list_data/') send_qq('影子', '更新' + stk + '离心度历史数据成功!')
def checkWeekStrayForAll(): towho = '影子2' send_qq(towho, '以下是今晚海选结果:') df_total = ts.get_stock_basics() # 过滤掉年龄小于四岁的 df_age_filter = df_total[df_total.apply(lambda x: int( str(x['timeToMarket'])[:4]) <= int(get_current_date_str()[:4]) - 4, axis=1)] # 根据week反转情况进行过滤,保留有反转的单位 df_age_filter_stray = list(df_age_filter.reset_index().apply( lambda x: (x['code'], week_MACD_stray_judge(x['code'], towho)), axis=1)) # 过滤掉非反转的情况 df_age_f2 = list(filter(lambda x: x[1][0], df_age_filter_stray)) # 增加stk的水平信息 df_level = [(x[0], x[1][1], calStkPlevel(x[1][1]['close'].values)) for x in df_age_f2] # 按总体水平排序,筛选优异者 df_level.sort(key=lambda x: x[2]['total_last']) df_level = df_level[:math.floor(len(df_level) / 3 * 2)] # 按照近30的波动率进行排序,筛选优异者 df_level.sort(key=lambda x: x[2]['std'], reverse=True) df_level = df_level[:math.floor(len(df_level) / 3 * 2)] # 按照近30的水平排序,留下最后8只 df_level.sort(key=lambda x: x[2]['t30_last'], reverse=False) df_level = df_level[:np.min([math.floor(len(df_level) / 3 * 2), 15])] # 打印信息 stk_list = [k[0] for k in df_level] for stk in stk_list: # 打印周与月信息 send_W_M_MACD(stk_code=stk, towho=towho) # 打印日线信息 df = get_k_data_JQ(stk, count=400, end_date=get_current_date_str()) fig, _, _ = genStkPicForQQ(df) plt.title(str(stk)) send_pic_qq(towho, fig) plt.close() fig, _, _ = genStkIdxPicForQQ(df) plt.title(str(stk)) send_pic_qq(towho, fig) plt.close()
def updateRSVRecord(): try: code_list = readConfig()['buy_stk'] # global RSV_Record for stk in code_list: RSV_Record[stk] = calRSVRank(stk, 5) except Exception as e: send_qq('影子2', 'RSV数据更新失败!\n' + str(e))
def updateRSVRecord(): try: (conn_opt, engine_opt) = genDbConn(localDBInfo, 'stk_opt_info') df = pd.read_sql(con=conn_opt, sql='select * from now') # global RSV_Record if not df.empty: for idx in df.index: RSV_Record[stk_code] = calRSVRank(df.loc[idx, 'stk_code'], 5) except: send_qq('影子2', 'RSV数据更新失败!')
def update_price_ratio_info(): """ :param df_H_L_Pot: :return: """ # 将结果序列化 with open(price_ratio_info_url, 'wb') as f: pickle.dump(h_l_pot_info, f) send_qq(u'影子', '高底线信息更新成功!')
def send_all_product_to_all_qun(qun_list_, product_list, text_st, pic_st, product_st): """ 将所有product 发送到所有群 :param qun_list_: :param product_list: :param sleep_time: :return: """ for qun in qun_list_: for product in product_list: send_single_product_to_single_qun(product, qun, text_st=text_st, pic_st=pic_st) time.sleep(product_st) # 附带加qun推广 send_qq(qun, add_qun_note)
def printMainRankForPublic(): """ 打印重要的index """ r = [(x, '%.2f' % (calRealtimeRankWithGlobal(stk_code=x)[0]), '%.2f' % (calRealtimeRankWithGlobal(stk_code=x)[2])) for x in ['sh', 'sz', 'cyb']] note = str([x[0]+'\n'+'上涨概率:'+str(x[1])+'%\n'+'当前值:'+str(x[2])+'\n' for x in r])\ .replace('sh', '上证')\ .replace('sz', '深证')\ .replace('cyb', '创业板')\ .replace('[', '')\ .replace(']', '')\ .replace("'", '')\ .replace('\\n', "\n")\ .replace(',', '--------------------\n') send_qq('大盘上涨概率公示', '\n\n--------------------\n' + note)
def saveWeightFile(): """ 将持仓stk的权值存为文件 :param dir: :return: """ # 新方式:lacalDBInfo包括除了“数据库名”之外的其他参数 localDBInfo = { 'host': 'localhost', 'port': 3306, 'user': '******', 'password': '******', 'charset': 'utf8' } db_name = 'stk_opt_info' table_history = 'history' table_now = 'now' (conn_opt, engine_opt) = genDbConn(localDBInfo, db_name) df = pd.read_sql(con=conn_opt, sql='select * from now') if not df.empty: df['weight'] = df.apply(lambda x: calWeight(x['stk_code']), axis=1) dumpPickle(data=df, saveLocation='./Weight/', fileName='weight') send_qq( '影子', '更新stk的权值成功!\n' + str(df.loc[:, ['stk_name', 'weight']].values)) else: dumpPickle(data=pd.DataFrame(), saveLocation='./Weight/', fileName='weight') send_qq('影子', '更新stk权值时发现 now 表为空!') conn_opt.close()
def myPrint(str_gui, str_temp, method='n', towho=''): """ :param gui: :param str_gui: :param method: :param towho: :return: """ if method is 'n': print(str_temp) elif method is 'gm': str_gui['msg'] = str_gui['msg'] + str_temp + '\n\n' elif method is 'gn': str_gui['note'] = str_gui['note'] + str_temp + '\n\n' elif method is 'qq': send_qq(towho, str_temp) return str_gui
def send_single_product_to_single_qun(product_dict, qun, pic_st, text_st): """ 向一个群发送一个产品 :param product_dict: :param qun: :return: """ # 发送介绍 if len(product_dict['product_introduce']) > 0: send_qq(qun, product_dict['product_introduce']) time.sleep(text_st) # 发送图片 if len(product_dict['product_image_list']) > 0: for image in product_dict['product_image_list']: send_qq_pic(qun, image) time.sleep(pic_st) # 发送buy key send_qq(qun, product_dict['product_buy_key']) time.sleep(text_st)
def printPredict2Public(): win_qq_name = u'大盘上涨概率公示' send_qq( win_qq_name, '各位:\n以下是下一个交易日大盘最高价、最低价和收盘价的预测,因为三个价格使用相互独立的模型,所以会出现收盘价低于最低价的情况,以及类似的情形,希望各位注意!' + '\n' + '周一~周五 晚上19:30 计算并发送该消息!\n格式及解释:\n' + "('high', '2989.57','0.11%')" + '\n' + '最高价, 2989.57, 相对于上一个收盘价的涨跌率 0.11, 训练时误差 0.852\n后面以此类推...') with open(rootPath + '\LSTM\AboutLSTM\stk_max_min.json', 'r') as f: max_min_info = json.load(f) for stk in ['sh', 'sz', 'cyb']: close_today = ts.get_k_data( stk, start=add_date_str(get_current_date_str(), -5)).tail(1)['close'].values[0] r = [(label, '%0.2f' % predict_tomorrow(stk, label, N_STEPS=N_STEPS, feature_cols=feature_cols, HIDDEN_SIZE=HIDDEN_SIZE, NUM_LAYERS=NUM_LAYERS), max_min_info[stk][label + '_acc']) for label in ['high', 'low', 'close']] # 增加与今天收盘价的对比 r_contrast = [ (x[0], x[1], '%0.2f' % ((float(x[1]) - close_today) / close_today * 100) + '%', x[2]) for x in r ] stk2name = {'sh': '上证', 'sz': '深证', 'cyb': '创业板'} send_qq(win_qq_name, stk2name[stk] + ':\n' + str(r_contrast))
def autoShutdown(): send_qq('影子', '120秒后将自动关机!') os.system('shutdown -s -f -t 120')
def JudgeSingleStk(stk_code, stk_price_last, stk_amount_last, earn_threshold, debug=True): # 获取该stk的实时价格,如果是大盘指数,使用聚宽数据,否则有限使用tushare if stk_code in ['sh', 'sz', 'cyb']: current_price = get_current_price_JQ(stk_code) else: try: current_price = get_RT_price(stk_code, source='ts') except: # current_price = get_RT_price(stk_code, source='jq') print(stk_code + '获取实时price失败!') return # 获取上次price stk_price_last = readLastP(stk_code) if stk_price_last < 0: saveLastP(stk_code, current_price) stk_price_last = current_price # 实时计算价差 price_diff = current_price - stk_price_last price_diff_ratio = price_diff / stk_price_last if debug: print(stk_code + ':\np_now:' + str(current_price) + '\np_last:' + str(stk_price_last) + '\np_change_ratio:' + str(price_diff_ratio)) if current_price == 0.0: print(stk_code + 'price==0.0! 返回!') return buy_amount = math.floor((money_each_opt / current_price) / 100) * 100 # 实时计算网格大小 earn_threshold_unit = getSigleStkReseau(stk_code) # 调节 buy 和 sale 的threshold if stk_code in RSV_Record.keys(): thh_sale = earn_threshold_unit * 2 * RSV_Record[stk_code] thh_buy = earn_threshold_unit * 2 * (1 - RSV_Record[stk_code]) else: thh_sale = -1 thh_buy = -1 # 计算其离心度分数 try: rank9, _, _, _ = calRealtimeRankWithGlobal(stk_code=stk_code) except: rank9 = -1 if debug: print(stk_code + ':\np_change:'+str(price_diff * stk_amount_last) + '\nthreshold:'+str(earn_threshold_unit) + \ '\nthh_sale:' + str(thh_sale) + \ '\nthh_buy:' + str(thh_buy)) # if (price_diff * stk_amount_last > earn_threshold*remind_ratio) & (price_diff * stk_amount_last < earn_threshold): # if JudgePChangeRatio(stk_code, price_diff_ratio): # send_qq('影子2', # "Near! S! "+stk_code + # '\nAmount:' + str(stk_amount_last) + # '\nP_now:' + str(current_price) + # '\nP_last:' + str(stk_price_last) + # '\nthreshold:' + str(earn_threshold) + # '\nM9_rank:' + str('%0.2f' % rank9) # ) # # el if price_diff > thh_sale: # if JudgePChangeRatio(stk_code, price_diff_ratio): send_qq( '影子2', "Reach! S! " + stk_code + '\nAmount:' + str(stk_amount_last) + '\nP_now:' + str(current_price) + '\nP_last:' + str(stk_price_last) + '\nthreshold_b:' + '%0.2f' % thh_buy + '\nthreshold_s:' + '%0.2f' % thh_sale + '\nM9_rank:' + str('%0.2f' % rank9)) saveLastP(stk_code, current_price) # # elif (price_diff*buy_amount > -earn_threshold)&(price_diff*buy_amount < -earn_threshold*remind_ratio): # send_qq('影子2', # "@Time Near! B! " + stk_code + # '\nAmount:' + str(buy_amount) + # '\nP_now:' + str(current_price) + # '\nP_last:' + str(stk_price_last) + # '\nthreshold:' + str(earn_threshold) + # '\nM9_rank:' + str('%0.2f' % rank9) # ) # elif price_diff < -thh_buy: # if JudgePChangeRatio(stk_code, price_diff_ratio): send_qq( '影子2', "@Time Reach! B! " + stk_code + '\nAmount:' + str(buy_amount) + '\nP_now:' + str(current_price) + '\nP_last:' + str(stk_price_last) + '\nthreshold_b:' + '%0.1f' % thh_buy + '\nthreshold_s:' + '%0.1f' % thh_sale + '\nM9_rank:' + str('%0.2f' % rank9)) saveLastP(stk_code, current_price) else: print(stk_code + ':未触发任何警戒线!')
# encoding=utf-8
def sendRelaLevel2QQ(): send_qq(towho='影子2', msge='注意低位囤货:') calRelaPLevel(readConfig()['safe_stk'], -720, '影子2')
def week_MACD_stray_judge(stk_code, towho, debug_plot=False): try: # 获取今天的情况,涨幅没有超过3%的不考虑 df_now = get_k_data_JQ(stk_code, count=2, end_date=get_current_date_str()).reset_index() if (df_now.tail(1)['close'].values[0] - df_now.head(1) ['close'].values[0]) / df_now.head(1)['close'].values[0] < -0.05: print('函数week_MACD_stray_judge:' + stk_code + '涨幅不够!') return False, pd.DataFrame() df = get_k_data_JQ(stk_code, count=400, end_date=get_current_date_str()).reset_index() if len(df) < 350: print('函数week_MACD_stray_judge:' + stk_code + '数据不足!') return False, pd.DataFrame() # 规整 df_floor = df.tail(math.floor(len(df) / 20) * 20 - 19) # 增加每周的星期几 df_floor['day'] = df_floor.apply(lambda x: calendar.weekday( int(x['date'].split('-')[0]), int(x['date'].split('-')[1]), int(x['date'].split('-')[2])), axis=1) # 增加每周的星期几 df_floor['day'] = df_floor.apply(lambda x: calendar.weekday( int(x['date'].split('-')[0]), int(x['date'].split('-')[1]), int(x['date'].split('-')[2])), axis=1) # 隔着5个取一个 if df_floor.tail(1)['day'].values[0] != 4: df_floor_slice_5 = pd.concat( [df_floor[df_floor.day == 4], df_floor.tail(1)], axis=0) else: df_floor_slice_5 = df_floor[df_floor.day == 4] # 计算指标 df_floor_slice_5['MACD'], df_floor_slice_5[ 'MACDsignal'], df_floor_slice_5['MACDhist'] = talib.MACD( df_floor_slice_5.close, fastperiod=6, slowperiod=12, signalperiod=9) # 隔着20个取一个(月线) df_floor_slice_20 = df_floor.loc[::20, :] # 计算指标 df_floor_slice_20['MACD'], df_floor_slice_20[ 'MACDsignal'], df_floor_slice_20['MACDhist'] = talib.MACD( df_floor_slice_20.close, fastperiod=4, slowperiod=8, signalperiod=9) # 获取最后的日期 date_last = df_floor_slice_5.tail(1)['date'].values[0] # 判断背离 MACD_5 = df_floor_slice_5.tail(3)['MACD'].values MACD_20 = df_floor_slice_20.tail(4)['MACD'].values if (MACD_5[1] == np.min(MACD_5)) & (MACD_20[1] != np.max(MACD_20)) & ( MACD_20[2] != np.max(MACD_20)): if debug_plot: """ --------------------------------------- 生成图片 -------------------------------------""" fig, ax = plot_W_M(df_floor_slice_5, df_floor_slice_20) # 增加标题 plt.title(stk_code + 'month-stray' + date_last) # 发送图片 send_pic_qq(towho, fig) # 关闭图片 plt.close() return True, df else: return False, pd.DataFrame() except Exception as e: send_qq(towho, stk_code + '出错:\n' + str(e)) return False, pd.DataFrame()
def checkDivergeLowLevel_Sub(stk_list, stk_list_name, scale_threshold, hist_data_dir, qq_win_name, desk=2, logic=True): """ :param stk_list: :param stk_list_name: :param scale_threshold: :param hist_data_dir: :param desk: :param logic: 为真时,大于阈值会触发,为假时,小于阈值会触发 :return: """ # 判断是否存在上次分数,存在则加载,否则初始化一个 if os.path.exists(LastScale+stk_list_name+'.dat'): lastscale_stk_pool = loadLastScale(stk_list_name) else: initScale(stk_list, stk_list_name) lastscale_stk_pool = loadLastScale(stk_list_name) for stk in stk_list: r, history_data, p_now, update_date = calRealtimeRankWithGlobal(stk_code=stk) # 生成语言描述 if (r-lastscale_stk_pool[stk]) > 0: note = '分数上涨'+'%0.1f' % (r-lastscale_stk_pool[stk]) else: note = '分数下落'+'%0.1f' % (r - lastscale_stk_pool[stk]) if logic: if considerMainIndex(stk, r): if math.fabs(r-lastscale_stk_pool[stk]) > desk: # 更新上次分数 lastscale_stk_pool[stk] = r send_qq(qq_win_name, 'Attention:\n' + stk + note + '\nscore:'+str('%0.2f') % r + '\np_now:' + str(p_now) + '\nhistory:' + str(history_data) + '\nupdate_date:' + str(update_date)) shelveP(lastscale_stk_pool, LastScale, stk_list_name) else: print('与上次命令相同!') else: print(stk+'分数处于正常状态!分数为:'+str('%0.2f') % r) else: if r < scale_threshold: if math.fabs(r-lastscale_stk_pool[stk]) > desk: # 更新上次分数 lastscale_stk_pool[stk] = r send_qq(qq_win_name, 'Attention:\n' + stk + note + '\nscore:' + str('%0.2f') % r + '\np_now:' + str(p_now) + '\nhistory:' + str(history_data) + '\nupdate_date:' + str(update_date)) shelveP(lastscale_stk_pool, LastScale, stk_list_name) else: print('与上次命令相同!') else: print(stk + '分数处于正常状态!分数为:' + str('%0.2f') % r)
""" note_str2 = \ """ 【快来兑换你的双11红I包,可赢额外红I包】https://m.tb.cn/h.etQyNSR?sm=64355a 嚸↑↓擊鏈ㄣ接,再选择瀏覽●噐○咑閞ヽ;或復ず■淛整句话¥orm1YuW897g¥后咑閞手机天猫 """ qun_list = \ list(set(get_all_win_by_name('找工作'))) + \ list(set(get_all_win_by_name('军事'))) + \ list(set(get_all_win_by_name('租房'))) while (get_current_datetime_str()[-8:] >= '06:00:00') & (get_current_datetime_str()[-8:] <= '23:00:00'): for qun in qun_list: try: send_qq(qun, note_str1) time.sleep(0.5) send_qq(qun, note_str2) time.sleep(0.5) # send_qq(qun, note_str3) # time.sleep(1.5) print(qun + ': 消息发送成功!\n------------------------\n\n') except Exception as e: print(qun + ': 消息发送失败!\n原因:\n' + str(e) + '\n------------------------\n\n') print('\n\n================== 大循环完成 ==================\n\n完成时间:' + get_current_datetime_str() + '\n') time.sleep(60 * 30)