涨停板
对于每天要复盘的股票高手们,经常会去关注当天的涨停板和跌停板,涨停板与跌停板的数目,可以很好反应当天的市场的情绪,比如千股涨停,千股跌停,半数涨停被砸开,什么天地板,地天板。
即使笔者不去打板,不去追题材,平时也会根据涨跌停的分布与封单数据作为考量市场,作为一个市场活跃因子和情绪量化指标。
比如下面是今天收盘后程序自动获取的数据。
有人问怎么自动?答:部署在某台电脑服务器,crontab设定定时任务即可。windows的话可以设置计划任务。
数据目前是存储到mysql,为什么不存其他类似excel?因为结构化的数据便于每天检索,处理运算,对接其他程序也方便,只需提供表名,库名即可,导出excel也是几行代码。
今日的涨停股
昨日涨停的今天涨幅
经常复盘的读者应该也很会用这个指标了,它以为昨天打板客今天是吃面还是吃肉的大概情况。
python代码实现
代码不复杂,主要去金融街的网站上爬2页数据即可,而且是实时的数据,也就是你在盘中运行,得到的是但是的盘中涨跌停分布。
1# 每天的涨跌停
2import sys
3sys.path.append('..')
4import re
5import time
6import os
7from configure.util import notify
8from configure.settings import config_dict
9import pandas as pd
10from configure.settings import DBSelector, send_from_aliyun
11import requests
12import datetime
13from common.BaseService import BaseService
14
15
16class GetZDT(BaseService):
17
18 def __init__(self, today=None):
19 ''' 20 TODAY 格式 20200701 21 :param today: 22 '''
23 super(GetZDT, self).__init__('log/zdt.log')
24
25 if today:
26 self.today = today
27 else:
28 self.today = time.strftime("%Y%m%d")
29
30 self.user_agent = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/64.0.3282.167 Chrome/64.0.3282.167 Safari/537.36"
31 self.path = config_dict('data_path')
32 self.zdt_url = f'http://home.flashdata2.jrj.com.cn/limitStatistic/ztForce/{self.today}.js'
33 self.zrzt_url = 'http://hqdata.jrj.com.cn/zrztjrbx/limitup.js'
34 self.host = "home.flashdata2.jrj.com.cn"
35 self.reference = "http://stock.jrj.com.cn/tzzs/zdtwdj/zdforce.shtml"
36
37 self.header_zdt = {"User-Agent": self.user_agent,
38 "Host": self.host,
39 "Referer": self.reference}
40
41 self.zdt_indexx = ['代码', '名称', '最新价格', '涨跌幅', '封成比', '封流比', '封单金额', '最后一次涨停时间', '第一次涨停时间', '打开次数',
42 '振幅',
43 '涨停强度']
44
45 self.zrzt_indexx = ['序号', '代码', '名称', '昨日涨停时间', '最新价格', '今日涨幅', '最大涨幅', '最大跌幅', '是否连板', '连续涨停次数',
46 '昨日涨停强度', '今日涨停强度', '是否停牌', '昨天的日期', '昨日涨停价', '今日开盘价格', '今日开盘涨幅']
47 self.header_zrzt = {"User-Agent": self.user_agent,
48 "Host": "hqdata.jrj.com.cn",
49 "Referer": "http://stock.jrj.com.cn/tzzs/zrztjrbx.shtml"
50 }
51
52 self.DB = DBSelector()
53
54 def download(self, url, headers, retry=5):
55
56 for i in range(retry):
57 try:
58 resp = requests.get(url=url, headers=headers)
59 content = resp.text
60 md_check = re.findall('summary|lasttradedate', content)
61 if content and len(md_check) > 0:
62 return content
63 else:
64 time.sleep(60)
65 self.logger.info('failed to get content, retry: {}'.format(i))
66 continue
67 except Exception as e:
68 notify(title='获取涨跌停数据出错', desp=f'{self.__class__}')
69 self.logger.error(e)
70 time.sleep(60)
71 continue
72
73 return None
74
75 def convert_json(self, content):
76 p = re.compile(r'"Data":(.*)};', re.S)
77 if len(content) <= 0:
78 self.logger.info('Content\'s length is 0')
79 exit(0)
80 result = p.findall(content)
81 if result:
82 try:
83 t1 = result[0]
84 t2 = re.sub('[\\r\\n]', '', t1)
85 t2 = re.sub(',,', ',0,0', t2)
86 t2 = re.sub('Infinity', '-1', t2)
87 t2 = re.sub('NaN', '-1', t2)
88 t2 = list(eval(t2))
89 return t2
90 except Exception as e:
91 notify(title='获取涨跌停数据出错', desp=f'{self.__class__}')
92 self.logger.info(e)
93 return None
94 else:
95 return None
96
97 def convert_dataframe(self, data, index, choice, post_fix):
98 engine = self.DB.get_engine('db_zdt', 'qq')
99 data_len = len(data)
100
101 if choice == 1:
102 for i in range(data_len):
103 data[i][choice] = data[i][choice]
104
105 df = pd.DataFrame(data, columns=index)
106
107 # 今日涨停
108 if choice == 1:
109 self.today_zt(df, post_fix, engine)
110 # 昨日涨停
111 if choice == 2:
112 self.yesterday_zt(df, post_fix, engine)
113
114 # 今日涨停存储
115 def today_zt(self, df, post_fix, engine):
116 filename = os.path.join(
117 self.path, self.today + "_" + post_fix + ".xls")
118
119 df['今天的日期'] = self.today
120 df.to_excel(filename, encoding='gbk')
121 try:
122 df.to_sql(self.today + post_fix, engine, if_exists='fail')
123 except Exception as e:
124 self.logger.info(e)
125
126 # 昨日涨停今日的状态,今日涨停
127 def yesterday_zt(self, df, post_fix, engine):
128 df = df.set_index('序号')
129 formula = lambda x: round(x * 100, 3)
130 df['最大涨幅'] = df['最大涨幅'].map(formula)
131 df['最大跌幅'] = df['最大跌幅'].map(formula)
132 df['今日开盘涨幅'] = df['今日开盘涨幅'].map(formula)
133 df['昨日涨停强度'] = df['昨日涨停强度'].map(lambda x: round(x, 0))
134 df['今日涨停强度'] = df['今日涨停强度'].map(lambda x: round(x, 0))
135
136 try:
137 df.to_sql(self.today + post_fix, engine, if_exists='fail')
138 except Exception as e:
139 notify(f'{self.__class__} 出错')
140 self.logger.info(e)
141
142 title,content = self.generate_html(df)
143 try:
144 send_from_aliyun(title, content, types='html')
145 except Exception as e:
146 self.logger.error(e)
147
148 def generate_html(self,df):
149 avg = round(df['今日涨幅'].mean(), 2)
150 median = round(df['今日涨幅'].median(), 2)
151 min_v = round(df['今日涨幅'].min(), 2)
152 min_index = df['今日涨幅'].argmin()
153 min_percent_name = df.iloc[min_index]['名称']
154 current = datetime.datetime.now().strftime('%Y-%m-%d')
155 title = '昨涨停今天{}平均涨{}\n'.format(current, avg)
156 content = '
昨天涨停今天{}
' \
157 '
平均涨幅 {}
' \
158 '
涨幅中位数 {}
' \
159 '
涨幅最小 {}
' \
160 '
涨幅最小股 {}
'.format(current, avg, median, min_v, min_percent_name)
161
162 return title,content
163 def start(self):
164 zdt_content = self.download(self.zdt_url, headers=self.header_zdt)
165 zdt_js = self.convert_json(zdt_content)
166 self.convert_dataframe(zdt_js, self.zdt_indexx, 1, 'zdt')
167 # 昨日涨停数据会如果不是当天获取会失效
168 zrzt_content = self.download(self.zrzt_url, headers=self.header_zrzt)
169 zrzt_js = self.convert_json(zrzt_content)
170 self.convert_dataframe(zrzt_js, self.zrzt_indexx, 2, 'zrzt')
171
172
173if __name__ == '__main__':
174 obj = GetZDT()
175 obj.start()
上述代码带有发送邮件功能,发送效果如上面有张邮件图一样的。
有了涨停/昨日涨停的个股的数据,接下来就顺便绘制一下每只个股的日K线图。当然,可以传入不同的参数,绘制周线,年线。
随便选一只放大后是这样的,肯定和东财,同花顺那些k先没得比的了。
根据开盘价,收盘价,最高价,最低价,成交量就可以绘制出个股的K线。
反正也就自己拿来看看趋势,后续会放入一个深度学习模型中,训练出一个模型,让它生成一个预测涨停板的模型,现在还是建模调参数当中,不过个人对结果还是不太看好哈。
PS:
现在改为用Markdown语法写公众号,感觉比微信的网页以html富文本写要舒服很多。
写完后用Md2All转下格式就可以发布了。
同时也请对我的排版多多包涵哈,个人觉得还是内容为王,太花俏而内容空洞的话是浪费你们的生命(鲁迅说的,浪费别人时间,如同谋财害命)。
后续大概会搭个数据服务器,把每天采集的数据分享出来,目前粉丝不多服务器还可以扛得住,或者计划写个小程序(没搞过,不知道好不好做,貌似基于JS和前端开发)。
由于微信改版后不再是按时间顺序推送文章,如果后续想持续关注笔者的最新观点,请务必将公众号设为星标,并点击右下角的“赞”和“在看”,不然我又懒得更新了哈,还有更多很好玩的数据等着你哦。