前言
前几天读到一篇微信公众号的文章熬了一晚上,小白用Python写了一个股票提醒系统,看了评论之后感觉意犹未尽,随心血来潮写下这篇文章,以纪念此刻的心情。
架构篇
基本上按照作者的思路可以顺利的完成整个股票提醒系统,本文在原作者的基础上增加了如下内容:
- 查询多支股票实时价格信息
- 增加微信信息通知、提醒以及告警
- 通过微信更新所选股票的买入下限阈值和卖出上限阈值
实现篇
实时获取股票价格
这部分内容与作者的基本一致,没啥好说的。
邮件系统
这部分内容,我按照我之前写过的脚本运行,其代码如下:
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
'''
@author: Haffner2010
@contact: myprojtest@example.com
@Software: Pycharm + Python3.6
@OS:Windows 7 64 bit
@Site:https://www.jianshu.com/u/e031670b216b
@file: EmailAutoSend.py
@time: 2018/4/1 20:03
@desc:
'''
#MIME邮件格式分析及信息提取http://www.pythonclub.org/python-files/mime-type
# SMTP模块
import smtplib
from email.mime.text import MIMEText
from email.header import Header
def MySMTP(UserInfo,Message):
SmtpServer=UserInfo['server']
user=UserInfo['username']
port=UserInfo['port']
Receiver=UserInfo['receiver']
# print(type(str(Receiver)))
sender=user # 发件人和登录账户名是同一个地址
password=UserInfo['password']
Message['From'] = sender
Message['To'] = Receiver
# Message['To'] = ";".join(Receiver)
# Message['Subject'] = Header(Subject, 'utf-8')
if port==25:
smtp=smtplib.SMTP(SmtpServer,port)
elif(port==465 or port==994):
smtp = smtplib.SMTP_SSL(SmtpServer, port) # 使用SSL加密登录,详见http://help.163.com/09/1223/14/5R7P3QI100753VB8.html
else:
print('SMTP协议端口号有误,请核对信息!')
smtp.helo(SmtpServer)
smtp.ehlo(SmtpServer)
# smtp.starttls() # 启动安全传输模式
smtp.login(user, password)
smtp.sendmail(sender, Receiver, Message.as_string())
print('Mail sent successfully!')
smtp.quit()
# 一些基本账户信息的定义
myaccinfo={
'username':'your_account@example.com', # 登录账户
'password' : 'Auth Code', # 此为授权码,非登录密码
'receiver':'your_account@example.com',
'server' : 'smtp.example.com', # 邮箱服务器地址
'port':25 # 登录端口号
}
if __name__=="__main__":
# 邮件信息
subject = 'subject'
# 纯文本邮件定义,邮件正文内容
msg = MIMEText('main body text', 'plain', 'utf-8')
# 定义发送人,接收人,以及描述信息(主题)
msg['Subject'] = Header(subject, 'utf-8')
MySMTP(myaccinfo,msg)
其中,基本账户信息中需要修改为自己邮箱的用户名和密码,以及邮箱登陆可以通过POP3、SMTP和IMAP来查看相关服务,并按照要求修改如下信息:
# 一些基本账户信息的定义
myaccinfo={
'username':'your_account@example.com', # 登录账户
'password' : 'Auth Code', # 此为授权码,非登录密码
'receiver':'your_account@example.com',
'server' : 'smtp.example.com', # 邮箱服务器地址
'port':25 # 登录端口号
}
邮件自动发送的代码,可以参考廖大的文章SMTP发送邮件加以了解。
邮件自动发送的源码已上传到我的GitHub上AutoEmailSend.py
关于邮件发送,最近看到一个不错的项目zmail,但我没用过,只是看介绍好像不错的样子。。
预警系统
预警系统,首先就要设置好预警值,我们以五大行为例,进行相关设置:
stock_code=['601288','601328','601988','601398','601939']
stock=Stock(q,stock_code)
setting={
'农业银行':[3.45,3.5],
'交通银行':[5.4,5.7],
'中国银行':[3.4,3.5],
'工商银行':[5.3,5.4],
'建设银行':[6.5,6.9]
} # 设置股票的期望买入下线和卖出上限
stock_code为五大行的股票代码,setting字典为我们期望买入以及卖出的价格区间。
死循环监控数据
在部分代码在原作者的基础上进行修改,代码如下:
while True:
now_dt = datetime.datetime.now() # 当前股价查询时间
if not start_dt < now_dt < stop_dt:
title = f'Current Time {now_dt} is not between {start_dt} and {stop_dt},we will stop!'
print(title)
bot.file_helper.send(title)
# 邮件信息
subject = 'Stop Running!'
# 纯文本邮件定义,邮件正文内容
msg = MIMEText(title, 'plain', 'utf-8')
# 定义发送人,接收人,以及描述信息(主题)
msg['Subject'] = Header(subject, 'utf-8')
MySMTP(myaccinfo, msg)
stock.stop_run() # 不在开市范围内,停止执行
break
if not q.empty():
cur_price_dict = q.get()
print(cur_price_dict)
print(f'Current stock price:{cur_price_dict}')
for item in cur_price_dict:
cur_price = float(cur_price_dict[item])
if cur_price > setting[item][1]:
title = f'股票[{item}]:当前价格{cur_price},高于max:{setting[item][1]}'
print(title)
bot.file_helper.send(title)
# 邮件信息
subject = '高阈值警告!'
# 纯文本邮件定义,邮件正文内容
msg = MIMEText(title, 'plain', 'utf-8')
# 定义发送人,接收人,以及描述信息(主题)
msg['Subject'] = Header(subject, 'utf-8')
MySMTP(myaccinfo, msg)
time.sleep(3)
if cur_price < setting[item][0]:
title = f'股票[{item}]:当前价格{cur_price},低于min:{setting[item][0]}'
print(title)
bot.file_helper.send(title)
# 邮件信息
subject = '低阈值警告!'
# 纯文本邮件定义,邮件正文内容
msg = MIMEText(title, 'plain', 'utf-8')
# 定义发送人,接收人,以及描述信息(主题)
msg['Subject'] = Header(subject, 'utf-8')
MySMTP(myaccinfo, msg)
time.sleep(3)
第一个if not语句表示如果不在开市时间范围内则停止运行,退出程序。
第二个if not语句中的for循环用来实时查询当前价格与买入价和卖出价的关系,高于卖出价或者低于买入价都通过邮件以及微信文件传输助手进行提醒。
setting区间阈值更新
本部分在原作者的基础上进行增加,用了wxpy提供的API,方便实时修改setting
# 消息接收监听器,通过接收文件传输助手的信息获取个人最新配置
@bot.register(chats=file_helper, except_self=False)
def print_others(message):
# 输出监听到的消息
print(message) # 此处的消息每次只能修改一只股票信息,对于实际应用来说已经足够
msg_price = re.search('(.*?) : (.*?) \(Text\)', str(message)).group(2)
print(msg_price)
try: # 格式code:high_pri,low_pri
code, low_pri, high_pri = re.split('[:, ]', msg_price)
print(code, low_pri, high_pri)
name = ts.get_realtime_quotes(code)[['name']].values[0][0]
setting.update({name:[float(low_pri),float(high_pri)]})
print(setting)
except:
print('nothing')
# return msg_price # 本来想通过return给外部函数接收以便修改setting的数据的,结果不知道如何使用,只能在register里面处理setting
关于return的内容如果有哪位大神知道还请告知,多谢!
整个股票提醒系统的源码见share.py
看看效果
刚开始设置了三家银行的高阈值低于当前价,微信端收到如下告警信息:
接下来提高农行的高阈值告警值,新的微信告警信息如下:
后记
大多数内容均来源于网络,如果构成侵权请联系删除。如果有什么不懂的可以一起交流,我也是初学者哈~~~