vnpy/vn.trader/utilSinaClient.py
2017-05-11 11:37:35 +08:00

385 lines
14 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# encoding: UTF-8
from __future__ import print_function
'''一个简单的SINA数据客户端主要使用requests开发'''
import requests
from time import sleep
import execjs
from datetime import datetime, timedelta
from ctaStrategy.ctaBase import CtaBarData, CtaTickData
class UtilSinaClient(object):
# ----------------------------------------------------------------------
def __init__(self, strategy):
self.strategy = strategy
requests.adapters.DEFAULT_RETRIES = 5
self.session = requests.session()
self.session.keep_alive = False
def getTicks(self, symbol, callback):
# 从sina加载最新的M1数据
try:
url = u'http://stock2.finance.sina.com.cn/futures/api/json.php/InnerFuturesService.getInnerFutures5MLine?symbol={0}'.format(
symbol)
self.strategy.writeCtaLog(u'从sina下载{0}Tick数据 {1}'.format(symbol, url))
responses = execjs.eval(self.session.get(url).content.decode('gbk').split('\n')[-1])
datevalue = datetime.now().strftime('%Y-%m-%d')
for j, day_item in enumerate(responses[str(symbol).upper()]):
for i, item in enumerate(day_item):
tick = CtaTickData()
tick.vtSymbol = symbol
tick.symbol = symbol
if len(item) >= 6:
datevalue = item[6]
tick.date = datevalue
tick.time = item[4] + u':00'
tick.datetime = datetime.strptime(tick.date + ' ' + tick.time, '%Y-%m-%d %H:%M:%S')
tick.lastPrice = float(item[0])
tick.volume = int(item[2])
if type(item[3]) == type(None):
tick.openInterest = 0
else:
tick.openInterest = int(item[3])
callback(tick)
return True
except Exception as e:
self.strategy.writeCtaLog(u'加载sina历史Tick数据失败' + str(e))
return False
def getTicks2(self, symbol, callback):
# 从sina加载最新的M1数据(针对中金所)
try:
#url = u'http://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20t1nf_{0}=/InnerFuturesNewService.getMinLine?symbol={0}'.format(symbol)
self.strategy.writeCtaLog(u'从sina下载{0}Tick数据 {1}'.format(symbol, url))
response_data= self.session.get(url).content
response_data = response_data.decode('gbk').split('=')[-1]
response_data = response_data.replace('(', '')
response_data = response_data.replace(');', '')
responses= execjs.eval(response_data)
datevalue = datetime.now().strftime('%Y-%m-%d')
for i, item in enumerate(responses):
tick = CtaTickData()
tick.vtSymbol = symbol
tick.symbol = symbol
if len(item) >= 6:
datevalue = item[6]
tick.date = datevalue
tick.time = item[0] + u':00'
tick.datetime = datetime.strptime(tick.date + ' ' + tick.time, '%Y-%m-%d %H:%M:%S')
tick.lastPrice = float(item[1])
tick.volume = int(item[3])
if type(item[4]) == type(None):
tick.openInterest = 0
else:
tick.openInterest = int(item[4])
callback(tick)
return True
except Exception as e:
self.strategy.writeCtaLog(u'加载sina历史Tick数据失败' + str(e))
return False
def getTicks3(self, symbol, callback):
# 从sina加载最新的5日内M1数据(针对中金所)
try:
url = u'http://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20t5nf_{0}=/InnerFuturesNewService.getFourDaysLine?symbol={0}'.format(symbol)
self.strategy.writeCtaLog(u'从sina下载{0}Tick数据 {1}'.format(symbol, url))
response_data= self.session.get(url).content
response_data = response_data.decode('gbk').split('=')[-1]
response_data = response_data.replace('(', '')
response_data = response_data.replace(');', '')
responses= execjs.eval(response_data)
datevalue = datetime.now().strftime('%Y-%m-%d')
for j, day_item in enumerate(responses):
for i, item in enumerate(day_item):
tick = CtaTickData()
tick.vtSymbol = symbol
tick.symbol = symbol
if len(item) >= 6:
datevalue = item[6]
tick.date = datevalue
tick.time = item[0] + u':00'
tick.datetime = datetime.strptime(tick.date + ' ' + tick.time, '%Y-%m-%d %H:%M:%S')
tick.lastPrice = float(item[1])
tick.volume = int(item[3])
if type(item[4]) == type(None):
tick.openInterest = 0
else:
tick.openInterest = int(item[4])
callback(tick)
return True
except Exception as e:
self.strategy.writeCtaLog(u'加载sina历史Tick数据失败' + str(e))
return False
def getMinBars(self, symbol, minute, callback):
"""# 从sina加载最新的M5,M15,M30,M60数据"""
if minute not in {5, 15, 30, 60}:
return False
sinaBars = []
try:
url = u'http://stock2.finance.sina.com.cn/futures/api/json.php/InnerFuturesService.getInnerFutures{0}MinKLine?symbol={1}'.format(minute,symbol)
self.strategy.writeCtaLog(u'从sina下载{0}{1}分钟数据 {2}'.format(symbol,minute, url))
responses = execjs.eval(self.session.get(url).content.decode('gbk').split('\n')[-1])
dayVolume = 0
for item in responses:
bar = CtaBarData()
bar.vtSymbol = symbol
bar.symbol = symbol
# bar的close time
sinaDt = datetime.strptime(item[0], '%Y-%m-%d %H:%M:00')
if minute in {5, 15} and sinaDt.hour == 10 and sinaDt.minute == 30:
# 这个是sina的bug它把10:15 ~10:30也包含进来了
continue
if minute == 60 and sinaDt.hour in {11,23,1,2} and sinaDt.minute == 30:
bar.datetime = sinaDt - timedelta(seconds=(minute /2)* 60)
else:
bar.datetime = sinaDt - timedelta(seconds=minute * 60)
bar.date = bar.datetime.strftime('%Y%m%d')
bar.tradingDay = bar.date # todo: 需要修改晚上21点后修改为next workingday
bar.time = bar.datetime.strftime('%H:%M:00')
bar.open = float(item[1])
bar.high = float(item[2])
bar.low = float(item[3])
bar.close = float(item[4])
bar.volume = int(item[5])
# 计算dayvolume
if not sinaBars:
dayVolume = bar.volume
else:
if sinaBars[-1].datetime.hour == 14 and bar.datetime.hour !=14:
dayVolume = bar.volume
else:
dayVolume += bar.volume
bar.dayVolume = dayVolume
sinaBars.append(bar)
if len(sinaBars)>0:
self.strategy.writeCtaLog(u'从sina读取了{0}{1}分钟数据'.format(len(sinaBars),minute))
# 把sina的bar灌入回调函数
for bar in sinaBars:
callback(bar)
# 处理完毕,清空
sinaBars = []
return True
else:
self.strategy.writeCtaLog(u'从sina读取{0}分钟数据失败'.format(minute))
return False
except Exception as e:
self.strategy.writeCtaLog(u'加载Sina历史分钟数据失败'+str(e))
return False
def getMinBars2(self, symbol, minute, callback):
"""# 从sina加载最新的M5,M15,M30,M60数据(针对中金所)"""
if minute not in {5, 15, 30, 60}:
return False
sinaBars = []
try:
timestamp = (datetime.utcnow() - datetime(1970, 1, 1)).total_seconds()
url=u'http://stock2.finance.sina.com.cn/futures/api/jsonp.php/var%20_{1}_{0}_{2}=/InnerFuturesNewService.getFewMinLine?symbol={1}&type={0}'.format(minute,symbol,timestamp)
#url = u'http://stock2.finance.sina.com.cn/futures/api/json.php/InnerFuturesService.getInnerFutures{0}MinKLine?symbol={1}'.format(minute,symbol)
self.strategy.writeCtaLog(u'从sina下载{0}{1}分钟数据 {2}'.format(symbol,minute, url))
response_data = self.session.get(url).content
response_data = response_data.decode('gbk').split('=')[-1]
response_data = response_data.replace('(', '')
response_data = response_data.replace(');', '')
responses = execjs.eval(response_data)
dayVolume = 0
for item in responses:
bar = CtaBarData()
bar.vtSymbol = symbol
bar.symbol = symbol
# bar的close time
sinaDt = datetime.strptime(item['d'], '%Y-%m-%d %H:%M:00')
if minute in {5, 15} and sinaDt.hour == 10 and sinaDt.minute == 30:
# 这个是sina的bug它把10:15 ~10:30也包含进来了
continue
if minute == 60 and sinaDt.hour in {11,23,1,2} and sinaDt.minute == 30:
bar.datetime = sinaDt - timedelta(seconds=(minute /2)* 60)
else:
bar.datetime = sinaDt - timedelta(seconds=minute * 60)
bar.date = bar.datetime.strftime('%Y%m%d')
bar.tradingDay = bar.date # todo: 需要修改晚上21点后修改为next workingday
bar.time = bar.datetime.strftime('%H:%M:00')
bar.open = float(item['o'])
bar.high = float(item['h'])
bar.low = float(item['l'])
bar.close = float(item['c'])
bar.volume = int(item['v'])
# 计算dayvolume
if not sinaBars:
dayVolume = bar.volume
else:
if sinaBars[-1].datetime.hour == 14 and bar.datetime.hour !=14:
dayVolume = bar.volume
else:
dayVolume += bar.volume
bar.dayVolume = dayVolume
sinaBars.append(bar)
if len(sinaBars)>0:
self.strategy.writeCtaLog(u'从sina读取了{0}{1}分钟数据'.format(len(sinaBars),minute))
# 把sina的bar灌入回调函数
for bar in sinaBars:
callback(bar)
# 处理完毕,清空
sinaBars = []
return True
else:
self.strategy.writeCtaLog(u'从sina读取{0}分钟数据失败'.format(minute))
return False
except Exception as e:
self.strategy.writeCtaLog(u'加载Sina历史分钟数据失败'+str(e))
return False
def getDayBars(self, symbol, callback):
"""# 从sina加载最新的Day数据"""
sinaBars = []
try:
url = u'http://stock.finance.sina.com.cn/futures/api/json.php/InnerFuturesService.getInnerFuturesDailyKLine?symbol={0}'.format(symbol)
self.strategy.writeCtaLog(u'从sina下载{0}的日K数据 {1}'.format(symbol, url))
responses = execjs.eval(self.session.get(url).content.decode('gbk'))
dayVolume = 0
for item in responses:
bar = CtaBarData()
bar.vtSymbol = symbol
bar.symbol = symbol
# bar的close time
bar.datetime = datetime.strptime(item['date'], '%Y-%m-%d')
bar.date = bar.datetime.strftime('%Y%m%d')
bar.tradingDay = bar.date # todo: 需要修改晚上21点后修改为next workingday
bar.time = bar.datetime.strftime('%H:%M:00')
bar.open = float(item['open'])
bar.high = float(item['high'])
bar.low = float(item['low'])
bar.close = float(item['close'])
bar.volume = int(item['volume'])
bar.dayVolume = bar.volume
sinaBars.append(bar)
if len(sinaBars)>0:
self.strategy.writeCtaLog(u'从sina读取了{0}条日线K数据'.format(len(sinaBars)))
# 把sina的bar灌入回调函数
for bar in sinaBars:
callback(bar)
# 处理完毕,清空
sinaBars = []
return True
else:
self.strategy.writeCtaLog(u'从sina读取日线K数据失败')
return False
except Exception as e:
self.strategy.writeCtaLog(u'加载Sina历史日线数据失败'+str(e))
return False
class TestStrategy(object):
def __init__(self):
pass
def addBar(self, bar):
print(u'{0},o:{1},h:{2},l:{3},c:{4},v:{5}'.format(bar.datetime, bar.open, bar.high, bar.low, bar.close, bar.volume))
def addTick(self, tick):
print(u'{0},{1},ap:{2},av:{3},bp:{4},bv:{5}'.format(tick.datetime, tick.lastPrice, tick.askPrice1, tick.askVolume1, tick.bidPrice1, tick.bidVolume1))
def writeCtaLog(self, content):
print(content)
if __name__ == '__main__':
t = TestStrategy()
sina = UtilSinaClient(t)
#rt=sina.getDayBars(symbol='RB1705', callback=t.addBar)
#rt = sina.getMinBars(symbol='RB1705',minute = 5, callback=t.addBar)
#rt = sina.getTicks(symbol='RB1705', callback=t.addTick)
#rt = sina.getTicks2(symbol='TF1706', callback=t.addTick)
#rt = sina.getTicks3(symbol='TF1709', callback=t.addTick)
rt = sina.getMinBars2(symbol='TF1709',minute=60, callback=t.addBar)