在2015年股市最高点入坑,一直亏到现在,虽然市值不多,但看到身边朋友一个个中了新股,略有激动,折腾良久,终于完成了python实现自动打新。虽然深知要打中概率极少,但此次编程过程中,学到了python、linux很多新姿势:
python对于http的操作,json的处理,数据类型转换,邮件发送,文件编码转换,数组数据提取
linux定时任务执行,时区、时间进制等等
记录下代码实现过程,期待能帮助到python入行新手,投身自动交易、量化交易的从业者们。
尝试了多个证券,要么证券公司不支持网上交易功能,要么数据包被加密,如国联证券的手机APP均被加密,最后发现中信建投网上营业厅能实现网上交易、打新等。
利用burp suite抓取登录过程,发现在登录时会先请求服务器某页面,利用返回的key加密账户密码、本地mac等,加密采用js实现,过程相当繁琐。
尝试利用python+selenium,但由于密码输入框为控件,selenium无法定位。
搜索到tushare包,利用tushare可实现对中信建投的登录、交易等,尝试去读tushare的源码,发现存在诸多困难,后采用了中转的方式。
1、利用tushare登录,tushare在登录过程中调用的requests包,在requests包的cookie处理代码处,添加代码,将当前cookie写入文件中;
2、读取文件中的cookie,获取当日可申购股票;
3、打新操作;
4、如打新成功发送邮件;
5、linux自动执行。
涉及代码:
Session cookie获取
1、修改requests包中的sessions.py文件
在文件头加入time包、re包
在629行处
extract_cookies_to_jar(self.cookies, request, r.raw)
# print self.cookies
for index,cookieitemin enumerate(self.cookies):
tmp = re.compile('Cookie (.*) for').findall(str(cookieitem))
timenow = time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())) +"---"
# f=open('tradelog.txt','a')
f=open('tradelog.txt','wb')
f.write(timenow)
f.write(tmp[0])
f.write('\r\n')
f.close()
#coding=utf-8
import urllib,urllib2,time,json
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import tushare as ts
import sys
reload(sys)
sys.setdefaultencoding( "utf-8" )
today_date = time.strftime('%Y-%m-%d',time.localtime(time.time()))
time_now = time.strftime('%m-%d %H.%M.%S',time.localtime(time.time()))
def sendMail(mailto,subject,body,format='plain'):
host,user,password,fromMail = "smtp.163.com","sendmailuser","sendmailpass","[email protected]"
_mailFrom = "TradeRobot"
if isinstance(body,unicode):
body = str(body)
me= ("%s<"+fromMail+">") % (Header(_mailFrom,'utf-8'),)
msg = MIMEText(body,format,'utf-8')
if not isinstance(subject,unicode):
subject = unicode(subject)
msg['Subject'] = subject
msg['From'] = me
msg['To'] = mailto
msg["Accept-Language"]="zh-CN"
msg["Accept-Charset"]="ISO-8859-1,utf-8"
try:
s = smtplib.SMTP()
s.connect(host)
s.login(user,password)
s.sendmail(me, mailto, msg.as_string())
s.close()
print "Email done"
return True
except Exception, e:
print str(e)
return False
def writeFile(filename,filecontent):
fp = open(filename,'a')
fp.write(filecontent)
fp.close()
def getHttp(url,mycookie):
headers={
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)',
'x-requested-with': 'XMLHttpRequest',
'Accept-Language': 'zh-CN',
'Referer': 'https://newetrade.csc108.com/login/main.jspx#',
'Accept': '*/*',
'Accept-Encoding': 'gzip, deflate',
'Connection': 'close',
'Cookie': mycookie
}
postData = {
}
postData = urllib.urlencode(postData)
request = urllib2.Request(url, postData, headers)
webhtml = urllib2.urlopen(request)
return webhtml.read()
def trade_login():
try:
ts.set_broker('zxjt',user='user1',passwd='password1')
tsc = ts.TraderAPI('zxjt')
tsc.login()
baseinfo = tsc.baseinfo()
print "login"
return True
except Exception,e:
print Exception,":",e
return False
def getCookie():
fp = open('tradelog.txt','rb')
mLines = fp.readlines()
fp.close()
targetLine = mLines[-1]
cookie_check = targetLine.split("---")[1].strip()
print "1-"+cookie_check
url='https://newetrade.csc108.com/mainHomePage/information_MyManage.json'
if 'mobilePhone'not in getHttp(url,cookie_check):
if trade_login():
time.sleep(3)
fp = open('tradelog.txt','rb')
mLines = fp.readlines()
fp.close()
targetLine = mLines[-1]
cookie_check = targetLine.split("---")[1].strip()
print "2-"+cookie_check
return cookie_check
else:
print "login failed"
writeFile(today_date+'error.txt',time.strftime('%m-%d %H.%M.%S',time.localtime(time.time()))+' login failed')
else:
return cookie_check
def get_today_xgsg(mycookie):
url_get_today_xgsg = 'https://newetrade.csc108.com/securityfind/newStockRepuchFindJson.json'
data_json = getHttp(url_get_today_xgsg,mycookie)
writeFile(time_now+'-xgsg.txt',data_json)
# print data_json
return data_json
#save in txt
def shen_gou():
shen_gou_url = 'https://newetrade.csc108.com/securityfind/xgsgcx.json?market=&_='
def write_custquota(mycookie):
try:
url_custquota = 'https://newetrade.csc108.com/securityfind/newStockRepurchEduQuery.json'
data_json = getHttp(url_custquota,mycookie)
s = json.loads(data_json)
for data1 in s["rows"]:
f=open('custquota.txt','wb')
f.write(data1['custquota'])
f.close()
except Exception,e:
print "custquota wirten ERROR"
print Exception,":",e
pass
def write_result(mycookie):
try:
url_custquota = 'https://newetrade.csc108.com/securityfind/zqcx.json'
result_json = getHttp(url_custquota,mycookie)
writeFile('shengou-result.txt',time_now+ '--' +result_json+'\r\n')
if u'没有符合查询条件的数据' in result_json:
print "中签查询结果:未中签"
else:
print "已中签或中签查询失败"
mailto1 = "[email protected]"
mailto2 = "[email protected]"
subject = "主题"
body = result_json
sendMail(mailto1,subject,body,format='plain')
sendMail(mailto2,subject,body,format='plain')
except Exception,e:
print "中签请求失败"
print Exception,":",e
pass
def read_custquota():
fp = open('custquota.txt','rb')
custquota = fp.readlines()
try:
if int(custquota[0]) > 500:
return int(custquota[0])
except:
custquota = '2000'
return int(custquota)
def json_trade(jsondata,mycookie):
custquota = read_custquota()
# print custquota
s = json.loads(jsondata)
sgjg = ''
sgsl= ''
sgdm =''
gddm =''
jysc=''
bsflag =''
for data1 in s["rows"]:
if ((data1['wsfxr'] ==today_date) and (data1['ssdd'] == u'上交所')):
# print data1
print data1['stockname']
print data1['ssdd']
print data1['sgdm']
print data1['fxj']
sgjg =sgjg + ','+str(data1['fxj'])
sgsl =sgsl + ','+str(custquota)
sgdm =sgdm + ','+str(data1['sgdm'])
gddm =gddm + ',A314437522'
jysc =jysc + ',1'
bsflag =bsflag + ',1'
sgjg= sgjg[1:]
sgsl= sgsl[1:]
sgdm= sgdm[1:]
gddm= gddm[1:]
jysc= jysc[1:]
bsflag= bsflag[1:]
payload = {'sgjg':sgjg, 'sgsl':sgsl, 'sgdm':sgdm, 'gddm':gddm, 'jysc':jysc, 'bsflag':bsflag}
payload = urllib.urlencode(payload)
url_trade = 'https://newetrade.csc108.com/securityfind/xgplsg.json'
url_trade_tmp = 'https://newetrade.csc108.com/securityfind/xgplsg.json?sgjg=%s&sgsl=%s&sgdm=%s&gddm=%s&jysc=%s&bsflag=%s'%(sgjg,sgsl,sgdm,gddm,jysc,bsflag)
# print url_trade_tmp
url_trade2 = '%s%s%s' % (url_trade,'?',payload)
# print url_trade2
result_trade = getHttp(url_trade_tmp,mycookie)
writeFile('result -'+ today_date + '.txt',time_now+ '--' +result_trade+'\r\n')
if '成功' in result_trade:
writeFile(today_date+'-ok.txt','1')
else:
print "Trade Failed"
print time_now
mycookie = getCookie()
write_custquota(mycookie)
print mycookie
json_data = get_today_xgsg(mycookie)
print "json_data is OK"
json_trade(json_data,mycookie)
print "中签check"
write_result(mycookie)
#print get_today_xgsg()
# if trade_login():
# get_today_xgsg()
#except Exception,e:
# print Exception,":",e
部署在kali linux上,建立定时任务,应确认时区、24小时制
/var/spool/cron/crontabs/root
50 10 * * * /bin/date >>/root/run.log
50 10 * * * /usr/bin/python trade.py>> /root/run.log
23 14 * * * /usr/bin/python trade.py >>/root/run.log
service cron restart
crontab -l