def OnTimerCtrl(win, debug=False): """ 定时器响应函数 :return: """ # 清屏 wx.PostEvent( win, ResultEvent(id=MSG_UPDATE_ID_S, data='检测时间:' + get_current_datetime_str() + '\n\n')) # 不在交易时间不使能定时器 if not is_in_trade_time(): wx.PostEvent( win, ResultEvent(id=MSG_UPDATE_ID_A, data='控制台定时器:当前不属于交易时间!\n')) return buy_stk_list = list( set(readConfig()['buy_stk'] + readConfig()['index_stk'])) if debug: print('OnTimerCtrl_4') # 局部变量 note_list = [] # 对股票进行检查 for stk in buy_stk_list: str_gui = JudgeSingleStk(stk_code=stk, stk_amount_last=400, qq='', gui=True) if len(str_gui['note']): note_list.append(str_gui['note']) # 打印流水信息 if len(str_gui['msg']): wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data=str_gui['msg'])) # 根据情况打印提示信息,并闪动 if len(note_list): # 清屏 wx.PostEvent( win, ResultEvent(id=NOTE_UPDATE_ID_S, data='检测时间:' + get_current_datetime_str() + '\n\n')) # 打印提示 for note in note_list: wx.PostEvent( win, ResultEvent(id=NOTE_UPDATE_ID_A, data=ChangeFontColor(note))) # 闪动图标提醒 wx.PostEvent(win, ResultEvent(id=FLASH_WINDOW_ID, data=None))
def on_timer_ctrl(win, debug=False): """ 控制台定时器响应函数 :return: """ # 清屏 wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_S, data='检测时间:' + get_current_datetime_str() + '\n\n')) # 不在交易时间不使能定时器 if (not is_in_trade_time()) & (not debug): wx.PostEvent(win, ResultEvent( id=MSG_UPDATE_ID_A, data='控制台定时器:当前不属于交易时间!\n')) return buy_stk_list = list(set(read_config()['buy_stk'] + read_config()['index_stk'])) # 局部变量 note_list = [] # 对stk进行检查 for stk in buy_stk_list: str_gui = judge_single_stk(stk_code=stk, stk_amount_last=400, qq='', gui=True, debug=True) if len(str_gui['note']): note_list.append(str_gui['note']) # 打印流水信息 if len(str_gui['msg']): wx.PostEvent(win, ResultEvent( id=MSG_UPDATE_ID_A, data=str_gui['msg'])) # 打印日志 debug_print_txt('timer_ctrl_log', 'total', get_current_datetime_str() + ':\n' + '提示消息:\n' + str(note_list) + '\n' + '流水消息:\n' + str(str_gui['msg'])) # 根据情况打印提示信息,并闪动 if len(note_list): # 清屏 wx.PostEvent(win, ResultEvent( id=NOTE_UPDATE_ID_S, data='检测时间:' + get_current_datetime_str() + '\n\n')) # 打印提示 for note in note_list: wx.PostEvent(win, ResultEvent( id=NOTE_UPDATE_ID_A, data=change_font_color(note))) # 闪动图标提醒 wx.PostEvent(win, ResultEvent( id=FLASH_WINDOW_ID, data=None))
def add_b_opt(self, price, amount): """ 记录买入操作 :return: """ b_opt = self.get_config_value('b_opt') if pd.isnull(b_opt): b_opt = [dict(time=get_current_datetime_str(), p=price, amount=amount)] else: b_opt = b_opt.append(dict(time=get_current_datetime_str(), p=price, amount=amount)) self.set_config_value('b_opt', b_opt)
def get_last_m_stray(self): """ 找出上一次穿越m线的情况 :return: """ # 取出一副本,再进行drop操作 df = self.data.dropna(axis=0) if df.empty: return '近期无穿越M%s均线(freq=%s)的行为' % (str(self.m), self.freq) # 取出最后一个转折点 df_pot = df[df.apply(lambda x: x['pn_pot_' + str(self.m)], axis=1)] if df_pot.empty: return '近期无穿越M%s均线(freq=%s)的行为' % (str(self.m), self.freq) last_pot = df_pot.tail(1) self.last_result = last_pot['m_pn_' + str(self.m)].values[0] return self.last_m_pot_note( get_current_datetime_str(), last_pot['datetime'].values[0], last_pot['m_pn_' + str(self.m)].values[0])
def add_s_opt(self, price, amount): """ 记录卖出操作 :return: """ s_opt = self.get_config_value('s_opt') if pd.isnull(s_opt): s_opt = [ dict(time=get_current_datetime_str(), p=price, amount=amount) ] else: s_opt = s_opt.append( dict(time=get_current_datetime_str(), p=price, amount=amount)) self.set_config_value('s_opt', s_opt)
def flash_window(self, evt=None): # 打印此次提示的时间 self.on_update_note_tc_a( '以上提示发生时间:' + get_current_datetime_str() + '\n----------------------------------------\n\n') win32gui.FlashWindowEx(self.handle, 2, 3, 400)
def add_opt_to_json_sub(input_str, json_file_url_, tc): # 返回字符串 return_str = [] # 已有文件,打开读取 if os.path.exists(json_file_url_): with open(json_file_url_, 'r') as _f: _opt_record = json.load(_f) else: _opt_record = {} # 解析输入 stk_name, opt, amount, p = input_str.split(' ') stk_code = name2code(stk_name) p, amount = float(p), float(amount) # 对输入格式进行检查 if amount % 100 != 0: tc.AppendText('格式错误!参考格式:\n美的集团 卖出 400 51.3') return if stk_code in _opt_record.keys(): opt_r_stk = _opt_record[stk_code] else: opt_r_stk = { 'b_opt': [], 'p_last': None, 'has_flashed_flag': True, 'total_earn': 0, 'last_prompt_point': -1 } if opt == '买入': opt_r_stk['b_opt'].append(dict(time=get_current_datetime_str(), p=p, amount=amount)) if opt == '卖出': if len(opt_r_stk['b_opt']) > 0: opt_r_stk, earn_this = sale_stk_sub(opt_r_stk, amount, p, tc) return_str.append('earn:' + str(earn_this) + '\n') opt_r_stk['p_last'] = p opt_r_stk['has_flashed_flag'] = True # 保存数据 _opt_record[stk_code] = opt_r_stk with open(json_file_url_, 'w') as _f: json.dump(_opt_record, _f) # 返回 return return_str
def is_in_trade_time(): """ 判断是否在交易时间,即 09:30~11:30 13:00~15:00 :return: """ r = get_current_datetime_str() h, m, s = r.split(' ')[1].split(':') t = int(h + m) if ((t > 930) & (t < 1130)) | ((t > 1300) & (t < 1500)): return True else: return False
def on_timer_pic(win, pool, debug=False): """ 图片定时器响应函数(闲置) :return: """ global last_upt_t upt_flag, last_upt_t = is_time_h_macd_update(last_upt_t) wx.PostEvent(win, ResultEvent(id=LAST_TIME_UPDATE_ID, data=last_upt_t)) if not upt_flag: wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data='图片更新定时器:“小时图片”更新时间点未到!\n')) return # 清屏 wx.PostEvent(win, ResultEvent(id=NOTE_UPDATE_ID_S, data='检测时间:' + get_current_datetime_str() + '\n\n')) # 生成更新的图片 wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data='开始更新小时图片...\n')) pic_dict = {'h_macd': gen_kind_pic('h', pool), 'h_idx': gen_kind_pic('h_idx', pool)} wx.PostEvent(win, ResultEvent(id=HOUR_UPDATE_ID, data=pic_dict)) wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data='小时图片更新完成!\n')) # 拐点检测 window_flash_flag = False for stk in list(set(read_config()['buy_stk'] + read_config()['concerned_stk'] + read_config()['index_stk'])): # 阈值条件不满足,该stk直接pass if not read_opt_json(stk, opt_record_file_url)['threshold_satisfied_flag']: wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data=code2name(stk) + '阈值条件不满足,不进行拐点检测\n')) continue hour_idx_str = check_single_stk_hour_idx_wx(stk, source='jq', debug=True) if len(hour_idx_str): window_flash_flag = True for str_tmp in hour_idx_str: wx.PostEvent(win, ResultEvent(id=NOTE_UPDATE_ID_A, data=change_font_color(str_tmp))) # 窗口闪烁 if window_flash_flag: wx.PostEvent(win, ResultEvent(id=FLASH_WINDOW_ID, data=None)) wx.PostEvent(win, ResultEvent(id=MSG_UPDATE_ID_A, data=note_sar_inflection_point))
def on_timer(self, event): fig, ax = plt.subplots(ncols=1, nrows=1, figsize=(6, 4)) plt.title('图' + get_current_datetime_str()) output = BytesIO() # BytesIO实现了在内存中读写byte fig.canvas.print_png(output) # fig.savefig(output, dpi=100) output.seek(0) img = wx.Image(output, wx.BITMAP_TYPE_ANY) output.close() # plt.close() imageRenderer = MyImageRenderer(wx.Bitmap(img)) self.grid.SetCellRenderer(0, 1, imageRenderer) self.grid.SetColSize(1, img.GetWidth() + 2) self.grid.SetRowSize(0, img.GetHeight() + 2) self.frame.Refresh()
def debug_print_txt(file_name, stk, value, enable=True): """ :param file_name: :param stk: :param value: :return: """ if not enable: return file_dir = data_dir + 'Debug_log/' + get_current_date_str() file_url = file_dir + '/' + file_name + '_' + stk + '.txt' # 如果文件夹不存在,创建 if not os.path.exists(file_dir): os.makedirs(file_dir) with open(file_url, 'a+') as f: f.write(get_current_datetime_str() + ':\n' + value + '\n')
def down_minute_data(stk_code, freq): try: df = get_k_data_JQ(stk_code, count=300, end_date=add_date_str(get_current_date_str(), 1), freq=freq) # 去掉volume为空的行 df = df.loc[df.apply(lambda x: not (x['volume'] == 0), axis=1), :] # 增加指标计算 df = add_stk_index_to_df(df) if str(df.index[-1]) > get_current_datetime_str(): df = df[:-1] return df except Exception as e_: # self.log = self.log + '函数down_minute_data:\n %s\n' % str(e_) print('函数down_minute_data:\n %s\n' % str(e_)) return pd.DataFrame()
def plot_w_m(df_w, df_m): """ :param df_w: :param df_m: :return: """ """ --------------------------------------- 生成图片 -------------------------------------""" fig, ax = subplots(ncols=1, nrows=4) ax[0].plot(range(0, len(df_w['date'])), df_w['close'], 'g*--', label='close') ax[1] = GenPic.plot_macd(ax[1], df_w, 'week') ax[1].plot(range(0, len(df_w['date'])), [0 for x in range(0, len(df_w['date']))], 'r--', label='week_MACD') ax[2].plot(range(0, len(df_m['date'])), df_m['close'], 'g*--', label='close') ax[3] = GenPic.plot_macd(ax[3], df_m, 'month') ax[3].plot(range(0, len(df_m['date'])), [0 for x in range(0, len(df_m['date']))], 'r--', label='month_MACD') # 设置默认标题 title_tmp = '上次更新时间:%s' % str(get_current_datetime_str()) ax[0].set_title(title_tmp) fig.tight_layout() # 调整整体空白 plt.subplots_adjust(wspace=0, hspace=0.15) # 调整子图间距 return fig, ax
def save_opt_info(self): """ 将操作日志打印到json :return: """ if opt_lock.acquire(): try: opt_record.append({ 'stk_code': self.stk_code, 'p_now': self.current_price, 'sale_reseau': self.thh_sale, 'buy_reseau': self.thh_buy, 'p_last': self.last_p, # 'opt': opt, 'date_time': get_current_datetime_str() }) except Exception as e: print('函数 JudgeSingleStk:写入操作记录失败!原因:\n' + str(e)) finally: opt_lock.release()
def gen_hour_macd_values(stk_code, source='jq', title=''): if source == 'jq': # df_30 = get_k_data_JQ(stk_code, start_date=add_date_str(get_current_date_str(), -20), # end_date=add_date_str(get_current_date_str(), 1), freq='30m') # df_60 = get_k_data_JQ(stk_code, start_date=add_date_str(get_current_date_str(), -20), # end_date=add_date_str(get_current_date_str(), 1), freq='60m') df_30 = get_k_data_JQ(stk_code, count=120, end_date=add_date_str(get_current_date_str(), 1), freq='30m') df_60 = get_k_data_JQ(stk_code, count=120, end_date=add_date_str(get_current_date_str(), 1), freq='60m') elif source == 'ts': df_30 = my_pro_bar(stk_code, start=add_date_str(get_current_date_str(), -20), freq='30min') df_60 = my_pro_bar(stk_code, start=add_date_str(get_current_date_str(), -20), freq='60min') # 去掉volume为空的行 df_30 = df_30.loc[df_30.apply(lambda x: not (x['volume'] == 0), axis=1), :] df_60 = df_60.loc[df_60.apply(lambda x: not (x['volume'] == 0), axis=1), :] df_30['MACD'], _, _ = talib.MACD(df_30.close, fastperiod=12, slowperiod=26, signalperiod=9) df_60['MACD'], _, _ = talib.MACD(df_60.close, fastperiod=12, slowperiod=26, signalperiod=9) # 生成图片 df_30 = df_30.dropna() df_60 = df_60.dropna() if str(df_60.index[-1]) > get_current_datetime_str(): df_30 = df_30[:-1] df_60 = df_60[:-1] return df_30, df_60
def gen_kind_pic(kind, pool): """ 造图片,存本地 :param kind: h:小时 h_idx:小时idx d:天 wm:周、月 idx: 指数 :return: 返回的图片应该 执行page和行号,便于更新! 以多层字典的方式返回结果,第一层区分page,第二层区分行号! """ r_dic = {'Index': {}, 'Buy': {}, 'Concerned': {}} dict_stk_hour = copy.deepcopy(dict_stk_list) jq_login() """ 在外部下载需要的数据,防止多进程中重复连接聚宽 """ for page in dict_stk_hour.keys(): for stk_info in dict_stk_list[page]: stk = stk_info[1] if kind is 'h': r_dic[page][stk + '_d'] = GenPic.gen_hour_macd_values(stk) elif kind is 'h_idx': r_dic[page][stk + '_d'] = GenPic.gen_hour_macd_values(stk)[0] elif kind is 'd': r_dic[page][stk + '_d'] = get_k_data_JQ(stk, 400) elif kind is 'wm': r_dic[page][stk + '_d'] = get_k_data_JQ( stk, count=400).reset_index() elif kind is 'd_idx': r_dic[page][stk + '_d'] = get_k_data_JQ(stk, 400) jq.logout() """ 生成pic """ for page in dict_stk_hour.keys(): for stk_info in dict_stk_list[page]: stk = stk_info[1] # 保存路径 save_dir = hist_pic_dir + get_current_date_str( ) + '/' + stk + kind + '/' file_name = get_current_datetime_str()[:-3].replace( ':', '').replace(' ', '').replace('-', '') + '.png' if not os.path.exists(save_dir): os.makedirs(save_dir) if kind is 'h': r_dic[page][stk + '_res'] = pool.apply_async( GenPic.gen_hour_macd_pic_local, (r_dic[page][stk + '_d'], stk, save_dir + file_name)) elif kind is 'h_idx': r_dic[page][stk + '_res'] = pool.apply_async( GenPic.gen_hour_index_pic_local, (r_dic[page][stk + '_d'], stk, save_dir + file_name)) elif kind is 'd': r_dic[page][stk + '_res'] = pool.apply_async( GenPic.gen_day_pic_local, (r_dic[page][stk + '_d'], stk, save_dir + file_name)) elif kind is 'wm': r_dic[page][stk + '_res'] = pool.apply_async( GenPic.gen_w_m_macd_pic_local, (r_dic[page][stk + '_d'], stk, save_dir + file_name)) elif kind is 'd_idx': r_dic[page][stk + '_res'] = pool.apply_async( GenPic.gen_idx_pic_local, (r_dic[page][stk + '_d'], stk, save_dir + file_name)) # if kind is 'h': # r_dic[page][stk + '_res'] = pool.apply_async(gen_hour_macd_pic_local, ( # r_dic[page][stk + '_d'], stk, 'jq', '', save_dir + file_name)) # # elif kind is 'h_idx': # r_dic[page][stk + '_res'] = pool.apply_async(gen_hour_index_pic_local, # (r_dic[page][stk + '_d'], stk, save_dir + file_name)) # elif kind is 'd': # r_dic[page][stk + '_res'] = pool.apply_async(gen_day_pic_local, # (r_dic[page][stk + '_d'], stk, save_dir + file_name)) # elif kind is 'wm': # r_dic[page][stk + '_res'] = pool.apply_async(gen_w_m_macd_pic_local, # (r_dic[page][stk + '_d'], stk, save_dir + file_name)) # elif kind is 'd_idx': # r_dic[page][stk + '_res'] = pool.apply_async(gen_idx_pic_local, # (r_dic[page][stk + '_d'], stk, save_dir + file_name)) # 在字典中保存图片路径 r_dic[page][stk + '_url'] = save_dir + file_name return r_dic
def get_t_now(): r = get_current_datetime_str() h, m, s = r.split(' ')[1].split(':') return int(h + m)
while True: input_str = input('输入你的命令:') # 按空格解析命令 input_split = input_str.split(' ') if len(input_split) == 4: # 插入命令 sql_str_no_reap = 'insert into ' +\ table_history + ' (stk_code, stk_name, amount, price, opt, input_time, reap_flag) values(' + \ "'" + input_split[0] + "'" + ',' + \ "'" + getNameByStkCode(g_total_stk_info_mysql, input_split[0]) + "'" + ',' + \ str(input_split[2]) + ',' + \ str(input_split[3]) + ',' + \ "'" + str(input_split[1]) + "'" + ',' + \ "'" + get_current_datetime_str() + "'" + ',' + \ "false" + \ ');' sql_str_reap = 'insert into ' +\ table_history + ' (stk_code, stk_name, amount, price, opt, input_time, reap_flag) values(' + \ "'" + input_split[0] + "'" + ',' + \ "'" + getNameByStkCode(g_total_stk_info_mysql, input_split[0]) + "'" + ',' + \ str(input_split[2]) + ',' + \ str(input_split[3]) + ',' + \ "'" + str(input_split[1]) + "'" + ',' + \ "'" + get_current_datetime_str() + "'" + ',' + \ "true" + \ ');' """ 300183 buy 300 13.25
# encoding=utf-8
""" 不用盖楼,复制下面的码,打开淘宝或者天猫,直接领红包,一般是几块钱,运气好的更高! """ 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完成时间:' +
def gen_hour_macd_pic(stk_data, debug=False, stk_code=''): if debug: print('进入GenPic.gen_hour_macd_pic函数!') debug_print_txt('macd_hour_pic', stk_code, '\n----------------------\n\n', enable=debug) # 生成小时macd数据 # df_30, df_60 = gen_hour_macd_values(stk_code, source=source, title=title) df_30, df_60 = stk_data if debug: debug_print_txt('macd_hour_pic', stk_code, 'df_30原始数据:\n' + str(df_30) + '\n\n' + 'df_60原始数据:\n' + str(df_60) + '\n\n', enable=debug) # 根据情况设置背景色 m30 = df_30.tail(3)['MACD'].values m60 = df_60.tail(3)['MACD'].values if debug: debug_print_txt( 'macd_hour_pic', stk_code, 'm30原始数据:\n' + str(m30) + '\n\n' + 'm60原始数据:\n' + str(m60) + '\n\n') if (m30[1] == np.min(m30)) | (m60[1] == np.min(m60)): # 设置背景红 GenPic.set_background_color('b_r') elif (m30[1] == np.max(m30)) | (m60[1] == np.max(m60)): # 设置背景绿 GenPic.set_background_color('b_g') else: GenPic.set_background_color() # 调整显示长度 df_30 = df_30.tail(40) df_60 = df_60.tail(40) fig, ax = plt.subplots(ncols=1, nrows=4) ax[0].plot(range(0, len(df_30)), df_30['close'], 'g*--', label='close_30min') ax[1] = GenPic.plot_macd(ax[1], df_30, '30min') ax[2].plot(range(0, len(df_60)), df_60['close'], 'g*--', label='close_60min') ax[3] = GenPic.plot_macd(ax[3], df_60, '60min') # 设置下标 ax[1] = addXticklabel_list( ax[1], list([str(x)[-9:-3] for x in df_30['datetime']]), 15, rotation=0, fontsize=6) ax[3] = addXticklabel_list( ax[3], list([str(x)[-9:-3] for x in df_60['datetime']]), 15, rotation=0, fontsize=6) for ax_sig in ax: ax_sig.legend(loc='best') # 设置默认标题 title = stk_code + ' ' + code2name(stk_code) + '/上次更新时间:%s' % str( get_current_datetime_str()) # 设置标题 if m30[1] == np.min(m30): title = stk_code + '半小时MACD低点!' elif m60[1] == np.min(m60): title = stk_code + '小时MACD低点!' elif m30[1] == np.max(m30): title = stk_code + '半小时MACD高点!' elif m60[1] == np.max(m60): title = stk_code + '小时MACD高点!' ax[0].set_title(title) if debug: debug_print_txt('macd_hour_pic', stk_code, '结论:' + title + '\n\n') fig.tight_layout() plt.subplots_adjust(wspace=0, hspace=0.15) # 调整子图间距 return fig
# encoding=utf-8
# encoding=utf-8
def gen_idx_pic(stk_df, stk_code=''): """ 打印常用指标 """ # 按升序排序 stk_df = stk_df.sort_values(by='date', ascending=True) """ 增加指标 'RSI5', 'RSI12', 'RSI30' 'SAR' 'slowk', 'slowd' 'upper', 'middle', 'lower' 'MOM' """ stk_df_ = add_stk_index_to_df(stk_df).tail(60) GenPic.set_background_color(bc='w') result_analysis = [] # 检查SAR attention = False sar_tail_origin = stk_df_.tail(2) sar_tail = sar_tail_origin.copy() sar_tail['compare'] = sar_tail_origin.apply( lambda x: x['SAR'] - x['close'], axis=1) title_tmp = stk_code + ' ' + code2name(stk_code) if sar_tail.head(1)['compare'].values[0] * sar_tail.tail( 1)['compare'].values[0] < 0: if sar_tail.tail(1)['SAR'].values[0] < sar_tail.tail( 1)['close'].values[0]: title_tmp = stk_code + ' ' + code2name( stk_code) + ' 注意 SAR 指标翻转,后续数天可能上涨!' result_analysis.append(title_tmp + RankNote.print_day_close_rank(stk_df)) GenPic.set_background_color(bc='b_r') else: title_tmp = stk_code + ' ' + code2name( stk_code) + ' 注意 SAR 指标翻转,后续数天可能下跌!' result_analysis.append(title_tmp + RankNote.print_day_close_rank(stk_df)) GenPic.set_background_color(bc='b_g') attention = True fig, ax = plt.subplots(nrows=5, ncols=1) ax[0].plot(range(0, len(stk_df_['date'])), stk_df_['RSI5'], 'b--', label='RSI5线', linewidth=1) ax[0].plot(range(0, len(stk_df_['date'])), stk_df_['RSI12'], 'r--', label='RSI12线', linewidth=1) ax[0].plot(range(0, len(stk_df_['date'])), stk_df_['RSI30'], 'g*--', label='RSI30', linewidth=0.5, markersize=1) ax[0].plot(range(0, len(stk_df_['date'])), [20 for a in range(len(stk_df_['date']))], 'b--', linewidth=0.3) ax[0].plot(range(0, len(stk_df_['date'])), [80 for a in range(len(stk_df_['date']))], 'b--', linewidth=0.3) ax[0].set_ylim(0, 100) ax[1].plot(range(0, len(stk_df_['date'])), stk_df_['SAR'], 'r--', label='SAR', linewidth=0.5, markersize=1) ax[1].plot(range(0, len(stk_df_['date'])), stk_df_['close'], 'g*--', label='close', linewidth=0.5, markersize=1) ax[2].plot(range(0, len(stk_df_['date'])), stk_df_['slowk'], 'g*--', label='slowk', linewidth=0.5, markersize=1) ax[2].plot(range(0, len(stk_df_['date'])), stk_df_['slowd'], 'r*--', label='slowd', linewidth=0.5, markersize=1) ax[2].plot(range(0, len(stk_df_['date'])), [20 for a in range(len(stk_df_['date']))], 'b--', linewidth=0.3) ax[2].plot(range(0, len(stk_df_['date'])), [80 for a in range(len(stk_df_['date']))], 'b--', linewidth=0.3) ax[2].set_ylim(0, 100) ax[3].plot(range(0, len(stk_df_['date'])), stk_df_['upper'], 'r*--', label='布林上线', linewidth=0.5, markersize=1) ax[3].plot(range(0, len(stk_df_['date'])), stk_df_['middle'], 'b*--', label='布林均线', linewidth=0.5, markersize=1) ax[3].plot(range(0, len(stk_df_['date'])), stk_df_['lower'], 'g*--', label='布林下线', linewidth=0.5, markersize=1) ax[4].plot(range(0, len(stk_df_['date'])), stk_df_['MOM'], 'g*--', label='MOM', linewidth=0.5, markersize=1) # 准备下标 xlabel_series = stk_df_.apply(lambda x: x['date'][2:].replace('-', ''), axis=1) ax[4] = add_axis(ax[4], xlabel_series, 40, rotation=45, fontsize=10) # 设置默认标题 title_tmp = stk_code + ' ' + code2name(stk_code) + '/上次更新时间:%s' % str( get_current_datetime_str()) ax[0].set_title(title_tmp) for ax_sig in ax: ax_sig.legend(loc='best', fontsize=5) fig.tight_layout() # 调整整体空白 plt.subplots_adjust(wspace=0, hspace=0) # 调整子图间距 ax[0].set_title(title_tmp) return fig, ax, attention, result_analysis
# encoding=utf-8
def gen_day_pic(stk_df, stk_code=''): """ 函数功能:给定stk的df,已经确定stk当前处于拐点状态,需要将当前stk的信息打印成图片,便于人工判断! :param stk_df 从tushare下载下来的原生df :param root_save_dir 配置文件中定义的存储路径 :return: 返回生成图片的路径 """ """ 规划一下都画哪些图 1、该stk整体走势,包括60日均线、20日均线和收盘价 2、stk近几天的MACD走势 """ """ 在原数据的基础上增加均线和MACD """ # 按升序排序 stk_df = stk_df.sort_values(by='date', ascending=True) stk_df['M20'] = stk_df['close'].rolling(window=20).mean() stk_df['M60'] = stk_df['close'].rolling(window=60).mean() stk_df['MACD'], stk_df['MACDsignal'], stk_df['MACDhist'] = talib.MACD( stk_df.close, fastperiod=12, slowperiod=26, signalperiod=9) # 检查日级别的MACD是否有异常 attention = False MACD_list = stk_df.tail(3)['MACD'].values if MACD_list[1] == np.min(MACD_list): attention = True # 设置背景红 GenPic.set_background_color('b_r') elif MACD_list[1] == np.max(MACD_list): attention = True # 设置背景绿 GenPic.set_background_color('b_g') else: GenPic.set_background_color() fig, ax = plt.subplots(nrows=4, ncols=1) ax[0].plot(range(0, len(stk_df['date'])), stk_df['M20'], 'b--', label='20日均线', linewidth=1) ax[0].plot(range(0, len(stk_df['date'])), stk_df['M60'], 'r--', label='60日均线', linewidth=1) ax[0].plot(range(0, len(stk_df['date'])), stk_df['close'], 'g*--', label='收盘价', linewidth=0.5, markersize=1) # ax[1].bar(range(0, len(stk_df['date'])), stk_df['MACD'], label='MACD') ax[1] = GenPic.plot_macd(ax[1], stk_df, 'day') # 准备下标 xticklabels_all_list = list(stk_df['date'].sort_values(ascending=True)) xticklabels_all_list = [ x.replace('-', '')[2:] for x in xticklabels_all_list ] for ax_sig in ax[0:2]: ax_sig = addXticklabel_list(ax_sig, xticklabels_all_list, 30, rotation=45) ax_sig.legend(loc='best', fontsize=5) # 画出最近几天的情况(均线以及MACD) stk_df_current = stk_df.tail(plot_current_days_amount) ax[2].plot(range(0, len(stk_df_current['date'])), stk_df_current['M20'], 'b--', label='20日均线', linewidth=2) ax[2].plot(range(0, len(stk_df_current['date'])), stk_df_current['M60'], 'r--', label='60日均线', linewidth=2) ax[2].plot(range(0, len(stk_df_current['date'])), stk_df_current['close'], 'g*-', label='收盘价', linewidth=1, markersize=5) ax[3] = GenPic.plot_macd(ax[3], stk_df_current, 'day') # 设置默认标题 title_tmp = stk_code + ' ' + code2name(stk_code) + '/上次更新时间:%s' % str( get_current_datetime_str()) ax[0].set_title(title_tmp) # 设置标题并返回分析结果 result_analysis = [] if MACD_list[1] == np.min(MACD_list): title_tmp = stk_code + ' ' + code2name( stk_code) + ' 日级别 MACD 低点!后续数天可能上涨!' ax[0].set_title(title_tmp) result_analysis.append(title_tmp + RankNote.print_day_close_rank(stk_df)) elif MACD_list[1] == np.max(MACD_list): title_tmp = stk_code + ' ' + code2name( stk_code) + ' 日级别 MACD 高点!后续数天可能下跌!' ax[0].set_title(title_tmp) result_analysis.append(title_tmp + RankNote.print_day_close_rank(stk_df)) # 准备下标 xticklabels_all_list = list( stk_df_current['date'].sort_values(ascending=True)) xticklabels_all_list = [ x.replace('-', '')[4:] for x in xticklabels_all_list ] for ax_sig in ax[2:4]: ax_sig = addXticklabel_list(ax_sig, xticklabels_all_list, 25, rotation=0) ax_sig.legend(loc='best', fontsize=2.5) fig.tight_layout() # 调整整体空白 plt.subplots_adjust(wspace=0, hspace=0.15) # 调整子图间距 # plt.close() return fig, ax, attention, result_analysis
# coding=utf-8
def prepare_trade_record(self, input_str, json_file_url_): # 返回字符串 return_str = [] # 已有文件,打开读取 if os.path.exists(json_file_url_): with open(json_file_url_, 'r') as _f: _opt_record = json.load(_f) else: _opt_record = {} # 解析输入 stk_code, opt, amount, p = input_str.split(' ') #stk_code = name2code(stk_name) stk_name = code2name(stk_code) p, amount = float(p), float(amount) # 对输入格式进行检查 #debug_print_txt('main_log', '', input_str +' ' + json_file_url_ + 'inside prepare_trade_record \n',True) if amount % 100 != 0: #tc.AppendText('格式错误!参考格式:\n美的集团 卖出 400 51.3') return if stk_code in _opt_record.keys(): opt_r_stk = _opt_record[stk_code] else: opt_r_stk = { 'b_opt': [], 's_opt': [], 'b_suggest': None, 's_suggest': None, 'p_last': None, 'has_flashed_flag': False, 'total_earn': 0, 'last_prompt_point': -1 } # 初步只支持每日一次操作 if opt_r_stk['has_flashed_flag'] == True: return if opt == '买入': opt_r_stk['b_opt'].clear() opt_r_stk['b_opt'].append(dict(time=get_current_datetime_str(), p=p, amount=amount, status='PRICE', entrust_no=0)) opt_r_stk['b_suggest'] = stk_name + ' 真买 ' + '%0.0f' % amount + ' ' + str(p) if opt == '卖出': #if len(opt_r_stk['b_opt']) > 0: opt_r_stk['s_opt'].clear() opt_r_stk['s_opt'].append(dict(time=get_current_datetime_str(), p=p, amount=amount, status='PRICE', entrust_no=0)) opt_r_stk['s_suggest'] = stk_name + ' 真卖 ' + '%0.0f' % amount + ' ' + str(p) #opt_r_stk, earn_this = sale_stk_sub(opt_r_stk, amount, p, tc) #return_str.append('earn:' + str(earn_this) + '\n') opt_r_stk['p_last'] = p opt_r_stk['has_flashed_flag'] = False # 保存数据 _opt_record[stk_code] = opt_r_stk with open(json_file_url_, 'w') as _f: #json.dump(_opt_record, _f) json.dump(_opt_record, _f, ensure_ascii=False, indent = 2, separators=(',', ': ')) # 返回 #debug_print_txt('main_log', '', stk_code +' end of prepare_trade_record \n',True) return return_str
def time_now(): print(str(get_current_datetime_str()))
# encoding=utf-8