初阳胜阴
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# encoding: utf-8 import decimal import requests import logging import logging.config import random import os import yaml import time import threading import re import datetime import json class Observer2(object): open_price_last_1 = '' close_price_last_1 = '' highest_price_last_1 = '' minimum_price_last_1 = '' ding_fen_xing = [] di_fen_xing = [] not_ding_di = [] def __init__(self): self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36', 'Connection': 'close'} self.chu_yang_sheng_yin = [] #self.stop_flag = False #self.potential_stock_list = self.get_potential_stock() #self.request_session = requests.session() def get_stock_data(self,stock_code,scale): """ 获取K 线数据 :param stock_code: 代码 :param scale: 级别 :return: k线数据 """ #url = 'http://ifzq.gtimg.cn/appstock/app/kline/mkline?param=sh600030,m30,,320&_var=m30_today&r=0.1700474168906776' url = 'http://ifzq.gtimg.cn/appstock/app/kline/mkline' params = { 'param': '{},m{},,320'.format(stock_code,scale), '_var': 'm{}_today'.format(scale), 'r': '0.1700474{}'.format("".join(random.choice("0123456789") for i in range(10))) } logging.info('url:%s \t params:%s',url,params) res = requests.get(url,params=params,headers=self.headers) res_str = res.content.decode('unicode_escape').rstrip() #logging.info('response:%s:',res_str) res_dict = eval(res_str[res_str.index("={")+1:res_str.index("}}}")+3]) scale_data = res_dict['data'][stock_code]['m'+scale] #logging.info(scale_data) return scale_data def get_stock_daily_data(self,stock_code): """ 获取日线数据 :param stock_code: 代码 :param scale: 级别 :return: k线数据 """ #url = 'http://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_dayqfq¶m=sh601857,day,,,320,qfq&r=0.44412021827221704' url = 'http://web.ifzq.gtimg.cn/appstock/app/fqkline/get' params = { '_var':'kline_dayqfq', 'param': '{},day,,,320,qfq'.format(stock_code), 'r': '0.1700474{}'.format("".join(random.choice("0123456789") for i in range(10))) } #logging.info('url:%s \t params:%s',url,params) res = requests.get(url,params=params,headers=self.headers) res_str = res.content.decode('utf-8') #logging.info('response:%s:',res_str) res_dict = eval(res_str.split('=')[1]) #logging.info('res_dict:%s:', res_dict) daily_data = [] if 'qfqday' in res_dict['data'][stock_code]: daily_data = list(res_dict['data'][stock_code]['qfqday']) elif 'day' in res_dict['data'][stock_code]: daily_data = list(res_dict['data'][stock_code]['day']) else : pass logging.info(daily_data) if self.is_chu_yang_sheng_yin(daily_data): self.chu_yang_sheng_yin.append(stock_code) return daily_data def is_chu_yang_sheng_yin(self,daily_data): if len(daily_data) > 10 and isinstance(daily_data,list): k0 = decimal.Decimal(daily_data[-1][1]) s0 = decimal.Decimal(daily_data[-1][2]) g0 = decimal.Decimal(daily_data[-1][3]) d0 = decimal.Decimal(daily_data[-1][4]) l0 = decimal.Decimal(daily_data[-1][5]) k1 = decimal.Decimal(daily_data[-2][1]) s1 = decimal.Decimal(daily_data[-2][2]) g1 = decimal.Decimal(daily_data[-2][3]) d1 = decimal.Decimal(daily_data[-2][4]) l1 = decimal.Decimal(daily_data[-2][5]) s_max_10 = max(decimal.Decimal(daily_data[-1][2]),decimal.Decimal(daily_data[-2][2]),decimal.Decimal(daily_data[-3][2]) ,decimal.Decimal(daily_data[-4][2]),decimal.Decimal(daily_data[-5][2]),decimal.Decimal(daily_data[-6][2]) ,decimal.Decimal(daily_data[-7][2]),decimal.Decimal(daily_data[-8][2]),decimal.Decimal(daily_data[-9][2]) ,decimal.Decimal(daily_data[-10][2])) is_jinshou_bt_zuokai = s0 > k1 is_zuokai_bt_zuoshou = k1 > s1 is_double_l = l0 < decimal.Decimal('2.5') * l1 and l0 > decimal.Decimal('1.4') * l1 is_jingao_lt_jinshou_m12 = g0 < s0 * decimal.Decimal('1.02') is_drzf_lt_4 = s0 < k0 * decimal.Decimal('1.04') is_drspj_lt_max10 = s0 * decimal.Decimal('1.1') < s_max_10 logging.info((is_jinshou_bt_zuokai,is_zuokai_bt_zuoshou,is_double_l,is_jingao_lt_jinshou_m12,is_drzf_lt_4,is_drspj_lt_max10)) if is_jinshou_bt_zuokai and is_zuokai_bt_zuoshou and is_double_l and is_jingao_lt_jinshou_m12 and is_drzf_lt_4 and is_drspj_lt_max10: return True else: return False def get_stock_code(self,a_type): """ 获取两市股票代码 :param a_type: sh or sz :return: stock_code """ #url = 'http://stock.gtimg.cn/data/index.php?appn=rank&t=rankash/chr&p=1&o=0&l=40&v=list_data' url = 'http://stock.gtimg.cn/data/index.php' params = { 'appn': 'rank', 't': 'ranka{}/chr'.format(a_type), 'p': 1, 'o': 0, 'l': 3000, 'v': 'list_data' } logging.info('url:%s \t params:%s', url, params) res = requests.get(url, params=params, headers=self.headers) res_str = res.content.decode('unicode_escape').rstrip() #logging.info('response:%s:',res_str) res_str_list = res_str[res_str.index("data:'") + 6:res_str.index("'}")].split(',') logging.info(res_str_list) return res_str_list def get_plate_data(self,stock_code): """ 获取盘中数据,如果出现大于80万的买单弹框提示 :param stock_code: :return: """ #url = 'http://web.sqt.gtimg.cn/q=sh601208?r=0.9884275211413494' url = 'http://web.sqt.gtimg.cn' params = { 'q': stock_code, 'r': '0.1700474{}'.format("".join(random.choice("0123456789") for i in range(10))) } logging.info('url:%s \t params:%s', url, params) res = requests.get(url, params=params, headers=self.headers) res_text = res.content.decode('GBK') logging.info('response:%s:',res_text.rstrip()) plate_data = res_text.split('~') stock_name_this = plate_data[1] stock_code_this = plate_data[2] for list_data in plate_data: if '|' in list_data: plate_date_strike = list_data.split('|') #logging.info(plate_date_strike ) buy_list = [] for plate_date_strike_detail in plate_date_strike: if 'B' in plate_date_strike_detail : buy_list.append(int(plate_date_strike_detail.split('/')[4])) logging.info(buy_list) if buy_list and max(buy_list) > 800000: logging.info('%s %s 动了' % (stock_name_this, stock_code_this)) self.alert_msg('%s %s 动了' % (stock_name_this, stock_code_this)) #self.stop_flag = True self.potential_stock_list.remove(stock_code) else: logging.info('%s %s 没动' % (stock_name_this, stock_code_this)) def get_potential_stock(self): potential_stock_list_new = [] stock_codes = self.get_stock_code('sh') + self.get_stock_code('sz') logging.info(('stock_codes',stock_codes)) stock_codes_length_div25 = int(len(stock_codes)/25) logging.info(stock_codes_length_div25) for stock_codes_length_div25_index in range(stock_codes_length_div25): logging.info(stock_codes_length_div25_index) if stock_codes_length_div25_index == stock_codes_length_div25 -1: req_str = ','.join(stock_codes[stock_codes_length_div25_index * 25:]) else: req_str = ','.join(stock_codes[stock_codes_length_div25_index * 25:(stock_codes_length_div25_index + 1) * 25]) url = 'http://qt.gtimg.cn/q=%s&r=9%s'%(req_str,''.join(str(i1) for i1 in random.sample(range(1,9),8))) logging.info(url) #res = requests.get(url, headers=self.headers) res = requests.session().get(url,headers=self.headers) res_str = res.content.decode('GBK').rstrip() stock_data_list = res_str.replace('\n','').split(';') for stock_data in stock_data_list: date_today = str(datetime.datetime.now()).split(' ')[0].replace('-','') day_rise_str_match = re.search(date_today + '(.*)?/',stock_data) logging.info(('day_rise_str_match',day_rise_str_match)) if day_rise_str_match : day_rise_str = day_rise_str_match.group(1) day_rise_float = float(day_rise_str.split('~')[2]) logging.info(('day_rise_float',day_rise_float)) #当日涨幅在4%和7%之间 if day_rise_float >4.0 and day_rise_float < 7.0: match_str = re.search('v_([s,h,z]{2}\d+)=.*',stock_data) if match_str: stock_code = match_str.group(1) # n天内涨停次数 > 6 if self.get_n_days_limit_up_times(stock_code,250) > 6 : potential_stock_list_new.append(stock_code) time.sleep(3) potential_stock_list_new = list(set(potential_stock_list_new)) logging.info(('potential_stock_list_new',potential_stock_list_new)) return potential_stock_list_new def is_potential_stock_list_changed(self): potential_stock_list_new = self.get_potential_stock() #如果交集等于并集则表示没有改变 if set(potential_stock_list_new) & set(self.potential_stock_list) == set(potential_stock_list_new) | set( self.potential_stock_list): return False else: self.stop_flag = True return True def get_n_days_limit_up_times(self,stock_code,n): date_n_ago = str(datetime.datetime.now() - datetime.timedelta(days=n)).split(' ')[0] date_today = str(datetime.datetime.now()).split(' ')[0] rand_str = '0.1700474{}'.format("".join(random.choice("0123456789") for i in range(10))) url = 'http://web.ifzq.gtimg.cn/appstock/app/fqkline/get?_var=kline_dayqfq¶m=%s,day,%s,%s,320,qfq&r=%s'%(stock_code,date_n_ago,date_today,rand_str) res = requests.get(url, headers=self.headers) res_str = res.content.decode('unicode_escape').rstrip().replace('kline_dayqfq=','') logging.info(res_str) logging.info(stock_code) #res_dict = json.loads(res_str) #day_kline_data = res_dict.get('data').get(stock_code).get('day') day_kline_data_match = re.search('\[\[(.*)?\]\]',res_str) if day_kline_data_match : day_kline_data_match_str = day_kline_data_match.group(1) day_kline_data_match_str = day_kline_data_match_str.replace('"','') day_kline_data = day_kline_data_match_str.split('],[') logging.info(day_kline_data) limit_up_times = 0 for i in range(len(day_kline_data)-1): if float(day_kline_data[i+1].split(',')[2])/float(day_kline_data[i].split(',')[2]) > 1.095 : limit_up_times = limit_up_times +1 return limit_up_times def monitor_start(self): #self.stop_flag = False for monitor_stock in self.potential_stock_list: m = MonitorThread(monitor_stock,self) m.start() def alert_msg(self,msg): commond = 'msg * %s'%msg os.system(commond) class MonitorThread(threading.Thread): def __init__(self,stock_code,observer): threading.Thread.__init__(self) self.name = stock_code self.stock_code = stock_code self.observer = observer def run(self): logging.info(self.name + '监控开始...') while 1: self.observer.get_plate_data(self.stock_code) if self.observer.stop_flag : break if self.observer.is_potential_stock_list_changed(): Observer2().monitor_start() break time.sleep(5) logging.info(self.name + '监控结束!') if __name__ == '__main__': path = 'logging.yaml' value = os.getenv('LOG_CFG', None) if value: path = value if os.path.exists(path): with open(path, "r") as f: config = yaml.load(f) logging.config.dictConfig(config) else: print('log config file not found!') observer2 = Observer2() stock_codes = observer2.get_stock_code('sh') + observer2.get_stock_code('sz') for stock_code in stock_codes : observer2.get_stock_daily_data(stock_code) logging.info(observer2.chu_yang_sheng_yin)