随着中国金融市场的发展,越来越多的中国人拥有了股票,特别是一些高收入的程序员和高级白领,往往都持有一定数量的股票,但是每时每刻人工盯盘还是很困难的,而且会被罚工资。。。。。。
而且随着量化交易的流行,程序化的股票交易已经越来越普通,作为个人投资者也可以拥有自己的量化交易系统,虽然我们散户想要调用券商的实盘交易接口有一定的难度,也存在安全风险,但是设计一个量化交易系统,由程序实时监测股票波动并发送预警邮件是具有可行性的。下面是我用python写的一个例子。
import tushare as ts#导入tushare模块,这是一个获取股票各种信息一个很常用的开源项目
import datetime
import time
import pandas as pd
import os
import sys
#导入纯文本邮件发送模块,这个模块可以参考网上的一些资料自己写一个适合自己的模块
import my_email as me
我采用的python环境是Anaconda这个最常用的数据分析平台,这个平台自带了很多数据分析用到的模块,不需要我们自己一个个去找,很方便,能让我们把更多的时间花在数据分析本身上。为了保证程序的可用性和简洁性,采用类封装所有函数和变量。
class monitor: #monitor类
period = 0 #一段时间长度,如5分钟
extent = 0 #一段时间内瞬时跌幅,如5分钟内涨跌幅
day_extent = 0 #日跌幅
day_range = 0 #日波动幅度
code = [] #股票代码数组
filebagPath = '' #工作路径
初始化函数
def __init__(self,code,period,extent,day_extent,day_range): #初始化函数
self.is_tradetime() #首先进行验证,当前时间是否为交易时间
self.code = code #初始化股票代码数组
self.period = period #初始化一段时间,设定时间长度
self.extent = extent #设定涨跌幅
self.day_extent = day_extent #初始化日最大涨跌幅
self.day_range = day_range #初始化日内股票最大振幅
path = os.getcwd() #得到当前工作目录
today_date = datetime.datetime.strftime(datetime.datetime.today(),'%Y%m%d') #得到今日日期,格式为“YYYYmmdd"
self.filebagPath = path + r'\monitor\%s'%today_date #建立以今日日期为名的文件路径,用来存储分笔数据
if os.path.exists(self.filebagPath): #判断文件夹是否已存在
pass
else:
os.makedirs(self.filebagPath) #不存在就新建该文件
判断是否交易时间的函数。
#判断当前是否交易时间的函数,方法是隔5秒获取一次实时分笔数据,如果获取的两次数据的时间一样则说明当前不是交易时间,程序终止
def is_tradetime(self):
trade_time1 = datetime.datetime.strptime(ts.get_realtime_quotes('sh')['time'][0],'%H:%M:%S')
time.sleep(5)
trade_time2 = datetime.datetime.strptime(ts.get_realtime_quotes('sh')['time'][0],'%H:%M:%S')
if trade_time1 == trade_time2:
print('当前不是交易时间!!!')
sys.exit()
监控股票波动的主函数。
def monitor(self): #主函数
for item in code: #新建对应code的csv文件来存储实时分笔数据
filePath = self.filebagPath + r'\%s.csv'%item
if os.path.exists(filePath): #如果文件已存在则用原来的
pass
else:
data = ts.get_realtime_quotes(item)
data.to_csv(filePath,encoding = 'gbk',index=False)
count = 0 #count用来记录抓取的次数
while 1: #循环
try:
now_data = ts.get_realtime_quotes(code) #一次性获取code数组里所有股票的实时分笔数据
for i in range(0,len(now_data)): #把获取到的实时分笔数据一一对应的存入对应的股票代码的.csv文件
now_code = now_data['code'][i]
filePath = self.filebagPath + '\%s.csv'%now_code
if list(pd.read_csv(filePath,encoding='gbk')['time'])[-1] == now_data['time'][i]: #如果新获取的数据和本地最新数据重合则放弃更新
pass
else: #不重合就更新对应代码的csv文件
now_data.loc[i:i].to_csv(filePath,mode = 'a',header = None,encoding = 'gbk',index=False)
used_data = pd.read_csv(filePath,encoding='gbk').head(20*self.period) #tushare每3s更新一次实时分笔数据,所以每分钟对应20次数据
self.__judge(used_data) #判断对应股票是否满足预设的条件
except:
pass
count = count + 1 #抓取数+1
print('执行第%s次monitor程序!!!'%count)
time.sleep(2) #延时2s,因为tushare每3S更新一次数据,所以太频繁的抓取数据没有意义
判断对应code股票是否满足预设条件的函数。
def __judge(self,used_data): #判断是否满足条件函数
flag = 0 #股票是否达到预警条件的标准标志,未达到为0,达到为1
if max(used_data['price']) - min(used_data['price']) > self.extent: #判断是否满足时间周期内的涨跌幅
flag = 1
if used_data['price'][len(used_data) - 1] > used_data['price'][0]: #如果后来的股票价格高就是涨
text_add = '%s 分钟涨幅超%s%%!!!'%(self.period,self.extent)
else: #如果后来的股票价格低就是跌
text_add = '%s 分钟跌幅超%s%%!!!'%(self.period,self.extent)
if 100*(used_data['price'][len(used_data) - 1] - used_data['pre_close'][0])/used_data['pre_close'][0] > self.day_extent:
#判断当前日涨幅是否达到预设条件
flag = 1
text_add = '当前涨幅超%s%%!!!'%(self.day_extent)
elif 100*(used_data['price'][len(used_data) - 1] - used_data['pre_close'][0])/used_data['pre_close'][0] < -1*self.day_extent:
#判断当前涨跌幅是否达到预设条件
flag = 1
text_add = '当前跌幅超%s%%!!!'%(-1*self.day_extent)
if 100*(used_data['high'][len(used_data) - 1] - used_data['low'][len(used_data) - 1])/used_data['pre_close'][0] > self.day_range:
#判断当前振幅是否达到预设值
flag = 1
text_add = '当日振幅达到%s%%!!!'%(-1*self.day_range)
if flag == 1:
now_change = (int(list(used_data['price'])[-1]) - int(list(used_data['pre_close'])[-1]))/int(list(used_data['pre_close'])[-1])
text = '%s %s %s 当前涨跌幅%s%% 开盘价%s 当前价格%s 总金额%s亿 时间%s' \
%(list(used_data['code'])[-1],list(used_data['name'])[-1],text_add,round(now_change,2) \
,list(used_data['open'])[-1],list(used_data['price'])[-1],used_data['amount'][0],used_data['time'][0])
#邮件要发送的文本信息
me.email(text) #发送邮件,该模块可以根据自己的需要在网上找一个
this_code = used_data['code'][0]
print(this_code)
self.code.remove(this_code) #将对于股票移出股票数组,避免重复预警
if len(self.code) == 0: #如果code数组里没有了股票就终止程序
print('所有code对应的股票全部达到预定条件并发送了预警邮件!!!')
sys.exit()
试验代码。
if __name__ == '__main__':
code = ['000958','002384','000063','000810','000988','002031','600601','000802','600405','002673', \
'000831','601319', '002413', '601162','002115','000066','600677','002256','600624','002054', \
'002156', '601519','300205','600536', '000563','601108', '600213'] #我的自选股
mo = monitor(code = code,period = 5,extent = 5,day_extent = 8,day_range = 10)
#设定条件为5分钟内涨跌幅超过5%,日涨跌幅超过8%,日振幅超过10%
mo.monitor() #执行程序
以上就是监控A股波动并发送预警邮件的所有程序,如果觉得对你有用的话就点个赞吧。
欢迎对量化交易和python感兴趣的同学关注我的微信公众号。