在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()



2、登录后打新,同时查询是否打新成功,如果成功将发送至2个邮箱。


#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","sendmailuser@163.com"
    _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 = "mail1@qzxdh.com"
            mailto2 = "mail2@qq.com"
            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



3、自动执行

部署在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


PYTHON 股票自动交易 基于GUI界面 python 股票自动下单_json