用Python做了一个 "盯盘机器人",还能邮件通知你!
裸睡的猪
共 14927字,需浏览 30分钟
· 2021-07-31
来源 | 数据分析与统计学之美
前言
(真正的剑技不是要依靠剑锋,而是个人的修行,投资也是如此,投资者的素养最为重要)
,因此应当把80%的时间与精力放到投资模型构建的思考上,20%的时间与精力放到编程实现上。思路
盯盘机器人的工作流程图及效果图
1. 程序工作流程图
2. 股价监控的效果
代码实现
1. 需要安装的第三方库及简要介绍
Tushare:一个免费、开源的python财经数据接口包,通过该库的get_realtime_quotes(code)的方法(code为目标证券的交易代码,包括股票和ETF基金的交易代码都可以),可以返回股票的当前报价和成交信息,返回值的数据类型为DataFrame,该DataFram包括name(证券名称),open(今日开盘价),pre_close(昨日收盘价),price(当前价格)...time(时间)等,根据本次需求,仅需要部分维度即可,其他的维度,读者可以自行通过print()打印方式查看所有的维度信息。 pandas:数据分析的核心库,因为调用Tushare库的get_realtime_quotes(code)方法返回DataFrame数据类型,所以需要该库对返回数据进行操作。 schedule:在证券交易中的制度中,有交易和休市时间,要实现程序的定时运行,该库必不可少,详见程序部分对该库用法的介绍。 smtplib:该库主要实现电子邮件的发送。 sys:在交易日的15:00以后已经闭市,为避免资源的浪费,此时可以调用sys.exit()方法实现程序的自动退出。 pyinstaller:用该库可以将程序打包成可执行的exe格式文件,便于程序的运行。
2. 程序代码实现
① 编写获取当前证券价格信息的方法
def get_now_jiage(code):
df = ts.get_realtime_quotes(code)[['name','price','pre_close','date','time']]
return df
“三峡能源”
的证券交易代码为“600905”。调用Tushare的get_realtime_quotes(‘600905’)方法,即可返回一个DataFrame类型的数据,根据功能需要,我们只需要获取name(股票名称)
、price(当前价格)
、pre_close(昨日收盘价)
、date(价格对应的日期)
和time(价格对应的时间)
即可。② 编写判断是否在交易时间段内的方法
暂停交易时间
。判断是否在暂停交易时间段的方法编写如下:def pd_ztjytime():#判断是否是交易时间
now_time = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
now_datetime = datetime.datetime.strptime(now_time, '%Y-%m-%d %H:%M:%S')
d1 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 11:30:01', '%Y-%m-%d %H:%M:%S')
d2 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d') + ' 13:00:00', '%Y-%m-%d %H:%M:%S')
delta1 = (now_datetime - d1).total_seconds()
delta2 = (d2-now_datetime).total_seconds()
if delta1>0 and delta2>0 : #在暂停交易的时间内
return True #在暂停的交易时间范围内,返回 True
else:
return False #不在暂停的交易时间范围内,返回 False
③ 编写监控股价的主体运行程序
def do_programe(code):
if pd_ztjytime()==False: #判断是否在暂停交易的时间范围内
info=get_now_jiage(code) #调用方法获取当前的DataFrame
now_jiage=float(info['price'][0]) #获取现价
name=info['name'][0] #获取证券名称
pre_close=float(info['pre_close'][0]) #获取昨日收盘价
riqi=info['date'][0] #获取现价对应的日期
sj=info['time'][0] #获取价格对应的时间
now_zdie=round((now_jiage-pre_close)/pre_close*100,2) #计算现在的涨跌幅
all_zdie=round((now_jiage-cbj)/cbj*100,2) #计算股票持有期间内总的涨跌幅,其中cbj为购买时候的成本价,需要约定全局变量
now_shizhi=round(shuliang*now_jiage,2) #计算股票现在的市值,其中shuliang为购买股票的数量,需要约定为全局变量
ykui=round(now_shizhi-cbj*shuliang,2) #计算股票现在总的盈亏
if (abs(now_zdie)>=3 and abs(now_zdie)<3.09) or (abs(now_zdie)>=6 and abs(now_zdie)<6.05) or (abs(now_zdie)>=9 and abs(now_zdie)<9.1) : #判断现在的涨跌幅是否在目标范围内
email_comment = []
email_comment.append('<html>')
email_comment.append('<b><p><h3><font size="2" color="black">您好:</font></h4></p></b>')
email_comment.append('<p><font size="2" color="#000000">根据设置参数,现将监控到'+name+'('+str(code)+')的证券价格异动消息汇报如下:</font></p>')
email_comment.append('<table border="1px" cellspacing="0px" width="600" bgcolor=' + color_bg_fg + ' style="border-collapse:collapse">')
email_comment.append('<tr>')
email_comment.append('<td align="center"><b>序号</b></td>')
email_comment.append('<td align="center"><b>购买单价</b></td>')
email_comment.append('<td align="center"><b>持股数</b></td>')
email_comment.append('<td align="center"><b>现价</b></td>')
email_comment.append('<td align="center"><b>现涨跌幅</b></td>')
email_comment.append('<td align="center"><b>总涨跌幅</b></td>')
email_comment.append('<td align="center"><b>现市值</b></td>')
email_comment.append('<td align="center"><b>盈亏额</b></td>')
email_comment.append('<td align="center"><b>异动时间</b></td>')
email_comment.append('</tr>')
email_comment.append('<tr>')
email_comment.append('<td align="center">'+str(1)+'</td>')
email_comment.append('<td align="center">'+str(cbj) + '</td>')
email_comment.append('<td align="center">' + str(shuliang) + '</td>')
email_comment.append('<td align="center">' + str(now_jiage) +'</td>')
email_comment.append('<td align="center">' + str(now_zdie) + '%</td>')
email_comment.append('<td align="center">' + str(all_zdie) + '%</td>')
email_comment.append('<td align="center">' + str(now_shizhi) + '元</td>')
email_comment.append('<td align="center">' + str(ykui) + '元</td>')
email_comment.append('<td align="center">' + str(riqi) +' '+str(sj) +'</td>')
email_comment.append('</tr>')
email_comment.append('</table>')
email_comment.append('<p><font size="2" color="black">祝:股市天天红,日日发大财!</font></p>')
email_comment.append('</html>')
send_msg = '\n'.join(email_comment)
send_Email(email_add[0], send_msg)
if (abs(now_zdie)>=3 and abs(now_zdie)<3.1) or (abs(now_zdie)>=6 and abs(now_zdie)<6.1) or (abs(now_zdie)>=9 and abs(now_zdie)<9.1)
send_Email(email_add[0], send_msg)
def send_Email(Email_address, email_text):
from_addr = '*****' #发出电子邮件的地址
password = '*****' #发出电子邮件的密码
title = '股票价格异动监控消息-' + datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') #电子邮件的标题
msg = MIMEText(email_text, 'html', 'utf-8') #电子邮件的格式是HTML
msg['From'] = from_addr
msg['To'] = Email_address
msg['Subject'] = title
try:
server = smtplib.SMTP_SSL('smtp.qq.com', 465)
server.login(from_addr, password) # 发送邮件
server.send_message(msg)
server.quit()
# print(Email_address+' send success!')
#send_info.append(Email_address + ' send success!\n')
except Exception as e:
a+1
# print(e)
#send_info.append(e + '\n')
#send_info.append(Email_address + ' send failed!\n')
# print(Email_address+' send failed!')
如何获取发件人的授权码呢?以QQ邮箱为例说明:
第三步:单击“开启”链接后,会有一个验证密保的过程。按照页面中的说明,向指定号码发送指定内容的手机短信,发送完毕后单击页面中的“我已发送”按钮,会弹出一个框,里面就包含SMTP授权码,把它复制并存储起来,方便以后调用。
④ 编写调用do_programe(code)的监控程序
def run():
while True:
do_programe('600905')
now_time=datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
d1 = datetime.datetime.strptime(now_time, '%Y-%m-%d %H:%M:%S')
d2 = datetime.datetime.strptime(datetime.datetime.now().strftime('%Y-%m-%d')+' 15:00:00', '%Y-%m-%d %H:%M:%S')
delta = d2 - d1
if delta.total_seconds()<=0:
sys.exit()
time.sleep(1)
⑤ 编写每天9点30分开始监控的主程序
if __name__ == '__main__':
schedule.every().day.at("09:30").do(run)
while True:
schedule.run_pending()
time.sleep(1)
⑥ 程序打包与自动运行
pyinstaller -w -F
程序路径\程序名.py 即可。其中-w表示生成的exe文件运行时不出现黑色的DOS界面,我们只需要该程序 “悄悄” 在后台运行即可。(这里的文件名是作者改的文件名)
的文件,表明程序在监控中。展望
(数只股票)
来动态监测股价和自动判断交易时点(比如MACD,均线,KDJ指标等)
,往往需要结合数据库技术,才能便于灵活构造股票池。评论
用 Shader 实现旗帜飘扬动画效果
我觉得对于刚入门 3D 编程的朋友来说,如果能够完成代码创建模型数据->创建材质->编写Shader动画这一系列,想必会有满满的成就感。今天就用 Cocos Creator 的 utils.MeshUtils.createMesh 接口,带大家感受一下这个流程。这个流程不仅可以用于新手学
COCOS
2
【第129期】程序员的新宠:三款终端工具,让你告别Xshell!
概述 WindTerm:跨平台的SSH利器 首先介绍的是WindTerm,这是一款使用C语言开发的跨平台SSH客户端。它不仅完全免费,而且没有商业使用的限制。WindTerm支持SSH v2、Telnet、Raw Tcp等协议,而且性能出色,甚至超过了FinalShell和Electerm。功能
前端微服务
0
你只是卡住了,你并没有被击垮
一旦思维僵化了,那就很难跟上这个真实世界的快节奏,更不可能自发地去发现自身问题,进而打破自己。思维僵化,会导致我们无法“活在当下,开放和接纳,并去做自己觉得重要的事情”。觉察自己思维僵化的特征,是改变的第一步。思维僵化导致了你的选择都是错误的。思维方式的不同,才是人跟人之间的不同。有的人遇到挫折了,
小Q聊产品
1
【比特币减半后价格表现大揭秘】历史数据告诉你什么?
加密货币现状的十张图表Glassnode 和 Coinbase 发布了《加密货币市场指南》,这是一个季度系列,旨在提供对加密货币市场主要发展的详细分析。以下是报告中引起我们注意的10张图表:1.比特币主导地位从50%上升至52%通常由减半引发的山寨季会降低比特币的主导地位,使其更倾向于新的山寨币。这
区块链头条
0
“渣女”怎样抵抗收入暴跌,去杭州找大厂程序员“接盘”
一位好友给我分享了一张图片,看过之后,我直呼毁三观。不知是哪位大厂员工蒙在鼓里多年,被“渣女”耍的团团转。这也难怪外面传“要嫁就嫁程序员,钱多话少死得早。”敢情成为了某些“心机女”的接盘侠。我不由得想起了曾经轰动一时的“程序员苏享茂事件”,被前妻翟欣欣索要千万跳楼自杀。我在网上详细查了这个案件资料。
Python涨薪研究所
0
盘点一个使用超级鹰识别验证码并自动登录的案例
点击上方“Python共享之家”,进行关注回复“资源”即可获赠Python学习资料今日鸡汤江上几人在,天涯孤棹还。大家好,我是皮皮。一、前言前几天在Python钻石交流群【静惜】问了一个Python实现识别验证码并自动登录的问题,提问截图如下:验证码的截图如下所示:二、实现过程这里大家激烈的探讨,【
IT共享之家
0
Python列表知识应知应会
点击上方“Go语言进阶学习”,进行关注回复“Go语言”即可获赠从入门到进阶共10本电子书今日鸡汤只在此山中,云深不知处。一、前言 在Python程序开发中,列表(List)经常会使用。假设一个班里有50个学生现需要统计每一个学生的总成绩情况,如果不使用列
Go语言进阶学习
0