bug fix
This commit is contained in:
parent
d22986a2a9
commit
22180cf239
@ -31,21 +31,33 @@ PERIOD_MAPPING['1month'] = '1M'
|
||||
|
||||
SYMBOL_LIST = ['ltc_btc', 'eth_btc', 'etc_btc', 'bch_btc', 'btc_usdt', 'eth_usdt', 'ltc_usdt', 'etc_usdt', 'bch_usdt',
|
||||
'etc_eth','bt1_btc','bt2_btc','btg_btc','qtum_btc','hsr_btc','neo_btc','gas_btc',
|
||||
'qtum_usdt','hsr_usdt','neo_usdt','gas_usdt']
|
||||
'qtum_usdt','hsr_usdt','neo_usdt','gas_usdt','bnb_usdt','eos_usdt']
|
||||
|
||||
|
||||
class BinanceData(object):
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def __init__(self, strategy):
|
||||
def __init__(self, strategy=None):
|
||||
"""
|
||||
构造函数
|
||||
:param strategy: 上层策略,主要用与使用strategy.writeCtaLog()
|
||||
:param strategy: 上层策略,主要用与使用writeLog()
|
||||
"""
|
||||
self.strategy = strategy
|
||||
self.client = Client('', '')
|
||||
|
||||
self.client = Client('-', '-')
|
||||
def writeLog(self,content):
|
||||
if self.strategy and hasattr(self.strategy,'writeCtaLog'):
|
||||
self.strategy.writeCtaLog(content)
|
||||
else:
|
||||
print(content)
|
||||
|
||||
def get_bars(self, symbol, period, callback, bar_is_completed=False, bar_freq=1, start_dt=None):
|
||||
def writeError(self,content):
|
||||
if self.strategy and hasattr(self.strategy,'writeCtaError'):
|
||||
self.strategy.writeCtaError(content)
|
||||
else:
|
||||
print(content,file=sys.stderr)
|
||||
|
||||
def get_bars(self, symbol, period, callback, bar_is_completed=False,bar_freq=1, start_dt=None):
|
||||
"""
|
||||
返回k线数据
|
||||
symbol:合约
|
||||
@ -53,10 +65,10 @@ class BinanceData(object):
|
||||
"""
|
||||
ret_bars = []
|
||||
if symbol not in SYMBOL_LIST:
|
||||
self.strategy.writeCtaError(u'{} 合约{}不在下载清单中'.format(datetime.now(), symbol))
|
||||
self.writeError(u'{} 合约{}不在下载清单中'.format(datetime.now(), symbol))
|
||||
return False,ret_bars
|
||||
if period not in PERIOD_MAPPING:
|
||||
self.strategy.writeCtaError(u'{} 周期{}不在下载清单中'.format(datetime.now(), period))
|
||||
self.writeError(u'{} 周期{}不在下载清单中'.format(datetime.now(), period))
|
||||
return False,ret_bars
|
||||
if self.client is None:
|
||||
return False,ret_bars
|
||||
@ -64,37 +76,107 @@ class BinanceData(object):
|
||||
binance_symbol = symbol.upper().replace('_' , '')
|
||||
binance_period = PERIOD_MAPPING.get(period)
|
||||
|
||||
self.strategy.writeCtaLog('{}开始下载binance:{} {}数据.'.format(datetime.now(), binance_symbol, binance_period))
|
||||
self.writeLog('{}开始下载binance:{} {}数据.'.format(datetime.now(), binance_symbol, binance_period))
|
||||
|
||||
bars = []
|
||||
try:
|
||||
bars = self.client.get_klines(symbol=binance_symbol, interval=binance_period)
|
||||
bar_len = len(bars)
|
||||
for i, bar in enumerate(bars):
|
||||
add_bar = CtaBarData()
|
||||
try:
|
||||
add_bar.vtSymbol = symbol
|
||||
add_bar.symbol = symbol
|
||||
add_bar.datetime = datetime.fromtimestamp(bar[0] / 1000)
|
||||
utcdatetime = datetime.utcfromtimestamp(bar[0] / 1e3)
|
||||
add_bar.date = add_bar.datetime.strftime('%Y-%m-%d')
|
||||
add_bar.time = add_bar.datetime.strftime('%H:%M:%S')
|
||||
add_bar.tradingDay = add_bar.date
|
||||
# 币安的交易日,是按照utc来计算的
|
||||
add_bar.tradingDay = utcdatetime.strftime('%Y-%m-%d')
|
||||
add_bar.open = float(bar[1])
|
||||
add_bar.high = float(bar[2])
|
||||
add_bar.low = float(bar[3])
|
||||
add_bar.close = float(bar[4])
|
||||
add_bar.volume = float(bar[5])
|
||||
ret_bars.append(add_bar)
|
||||
except Exception as ex:
|
||||
self.strategy.writeCtaError(
|
||||
self.writeError(
|
||||
'error when convert bar:{},ex:{},t:{}'.format(bar, str(ex), traceback.format_exc()))
|
||||
return False
|
||||
return False,ret_bars
|
||||
|
||||
if start_dt is not None and bar.datetime < start_dt:
|
||||
continue
|
||||
ret_bars.append(add_bar)
|
||||
|
||||
if callback is not None:
|
||||
callback(add_bar, bar_is_completed, bar_freq)
|
||||
# 最后一个bar,可能是不完整的,强制修改
|
||||
if i == bar_len -1 and bar_is_completed:
|
||||
# 根据秒数算的话,要+1,例如13:31,freq=31,第31根bar
|
||||
freq = int((datetime.now() - add_bar.datetime).total_seconds() / 60) + 1
|
||||
callback(add_bar, False, freq)
|
||||
else:
|
||||
callback(add_bar, bar_is_completed, bar_freq)
|
||||
|
||||
return True,ret_bars
|
||||
except Exception as ex:
|
||||
self.strategy.writeCtaError('exception in get:{},{},{}'.format(binance_symbol,str(ex), traceback.format_exc()))
|
||||
self.writeError('exception in get:{},{},{}'.format(binance_symbol,str(ex), traceback.format_exc()))
|
||||
return False,ret_bars
|
||||
|
||||
def download_bars(self, symbol, period, start_dt=None):
|
||||
"""
|
||||
返回k线数据
|
||||
symbol:合约
|
||||
period: 周期: 1min,3min,5min,15min,30min,1day,3day,1hour,2hour,4hour,6hour,12hour
|
||||
"""
|
||||
ret_bars = []
|
||||
|
||||
if symbol not in SYMBOL_LIST:
|
||||
self.writeError(u'{} 合约{}不在下载清单中'.format(datetime.now(), symbol))
|
||||
return ret_bars
|
||||
if period not in PERIOD_MAPPING:
|
||||
self.writeError(u'{} 周期{}不在下载清单中'.format(datetime.now(), period))
|
||||
return ret_bars
|
||||
if self.client is None:
|
||||
return ret_bars
|
||||
|
||||
binance_symbol = symbol.upper().replace('_', '')
|
||||
binance_period = PERIOD_MAPPING.get(period)
|
||||
|
||||
self.writeLog('{}开始下载binance:{} {}数据.'.format(datetime.now(), binance_symbol, binance_period))
|
||||
|
||||
try:
|
||||
bars = self.client.get_klines(symbol=binance_symbol, interval=binance_period)
|
||||
for i, bar in enumerate(bars):
|
||||
add_bar = {}
|
||||
try:
|
||||
bar_datetime = datetime.fromtimestamp(bar[0] / 1e3)
|
||||
utc_datetime = datetime.utcfromtimestamp(bar[0] / 1e3)
|
||||
add_bar['datetime'] = bar_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
||||
add_bar['date'] = bar_datetime.strftime('%Y-%m-%d')
|
||||
add_bar['time'] = bar_datetime.strftime('%H:%M:%S')
|
||||
add_bar['open'] = float(bar[1])
|
||||
add_bar['high'] = float(bar[2])
|
||||
add_bar['low'] = float(bar[3])
|
||||
add_bar['close'] = float(bar[4])
|
||||
add_bar['volume'] = float(bar[5])
|
||||
add_bar['tradingDay'] = utc_datetime.strftime('%Y-%m-%d')
|
||||
ret_bars.append(add_bar)
|
||||
except Exception as ex:
|
||||
self.writeError(
|
||||
'error when convert bar:{},ex:{},t:{}'.format(bar, str(ex), traceback.format_exc()))
|
||||
return ret_bars
|
||||
|
||||
if start_dt is not None and bar_datetime < start_dt:
|
||||
continue
|
||||
|
||||
return ret_bars
|
||||
except Exception as ex:
|
||||
self.writeError('exception in get:{},{},{}'.format(binance_symbol,str(ex), traceback.format_exc()))
|
||||
return ret_bars
|
||||
|
||||
if __name__ == '__main__':
|
||||
binance_data = BinanceData()
|
||||
bars = binance_data.download_bars(symbol='bnb_usdt', period='1day')
|
||||
|
||||
for bar in bars:
|
||||
print(bar['datetime'])
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
# 从okex下载数据
|
||||
from datetime import datetime, timezone
|
||||
|
||||
import sys
|
||||
import requests
|
||||
import execjs
|
||||
import traceback
|
||||
@ -11,13 +11,13 @@ from vnpy.trader.app.ctaStrategy.ctaBase import CtaBarData, CtaTickData
|
||||
period_list = ['1min','3min','5min','15min','30min','1day','1week','1hour','2hour','4hour','6hour','12hour']
|
||||
symbol_list = ['ltc_btc','eth_btc','etc_btc','bch_btc','btc_usdt','eth_usdt','ltc_usdt','etc_usdt','bch_usdt',
|
||||
'etc_eth','bt1_btc','bt2_btc','btg_btc','qtum_btc','hsr_btc','neo_btc','gas_btc',
|
||||
'qtum_usdt','hsr_usdt','neo_usdt','gas_usdt','eos_usdt']
|
||||
'qtum_usdt','hsr_usdt','neo_usdt','gas_usdt','eos_usdt','ada_usdt','xmr_usdt','zrx_usdt','zil_usdt']
|
||||
|
||||
|
||||
class OkexData(object):
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def __init__(self, strategy):
|
||||
def __init__(self, strategy=None):
|
||||
"""
|
||||
构造函数
|
||||
:param strategy: 上层策略,主要用与使用strategy.writeCtaLog()
|
||||
@ -29,6 +29,18 @@ class OkexData(object):
|
||||
self.session = requests.session()
|
||||
self.session.keep_alive = False
|
||||
|
||||
def writeLog(self,content):
|
||||
if self.strategy and hasattr(self.strategy,'writeCtaLog'):
|
||||
self.strategy.writeCtaLog(content)
|
||||
else:
|
||||
print(content)
|
||||
|
||||
def writeError(self,content):
|
||||
if self.strategy:
|
||||
self.strategy.writeCtaError(content)
|
||||
else:
|
||||
print(content,file=sys.stderr)
|
||||
|
||||
def get_bars(self, symbol, period, callback, bar_is_completed=False,bar_freq=1, start_dt=None):
|
||||
"""
|
||||
返回k线数据
|
||||
@ -38,24 +50,24 @@ class OkexData(object):
|
||||
ret_bars = []
|
||||
if symbol not in symbol_list:
|
||||
self.strategy.writeCtaError(u'{} {}不在下载清单中'.format(datetime.now(), symbol))
|
||||
return False,ret_bars
|
||||
return False,ret_bars
|
||||
|
||||
url = u'https://www.okex.com/api/v1/kline.do?symbol={}&type={}'.format(symbol, period)
|
||||
self.strategy.writeCtaLog('{}开始下载:{} {}数据.URL:{}'.format(datetime.now(), symbol, period,url))
|
||||
self.writeLog('{}开始下载:{} {}数据.URL:{}'.format(datetime.now(), symbol, period,url))
|
||||
|
||||
content = None
|
||||
bars = []
|
||||
try:
|
||||
content = self.session.get(url).content.decode('gbk')
|
||||
bars = execjs.eval(content)
|
||||
except Exception as ex:
|
||||
self.strategy.writeCtaError('exception in get:{},{},{}'.format(url,str(ex), traceback.format_exc()))
|
||||
return False,ret_bars
|
||||
|
||||
bars = execjs.eval(content)
|
||||
bar_len = len(bars)
|
||||
for i, bar in enumerate(bars):
|
||||
if len(bar) < 5:
|
||||
self.strategy.writeCtaError('error when import bar:{}'.format(bar))
|
||||
return False
|
||||
return False,ret_bars
|
||||
if i == 0:
|
||||
continue
|
||||
add_bar = CtaBarData()
|
||||
@ -71,17 +83,116 @@ class OkexData(object):
|
||||
add_bar.low = float(bar[3])
|
||||
add_bar.close = float(bar[4])
|
||||
add_bar.volume = float(bar[5])
|
||||
ret_bars.append(add_bar)
|
||||
except Exception as ex:
|
||||
self.strategy.writeCtaError('error when convert bar:{},ex:{},t:{}'.format(bar, str(ex), traceback.format_exc()))
|
||||
return False,ret_bars
|
||||
|
||||
if start_dt is not None and bar.datetime < start_dt:
|
||||
continue
|
||||
ret_bars.append(add_bar)
|
||||
|
||||
if callback is not None:
|
||||
callback(add_bar, bar_is_completed, bar_freq)
|
||||
# 最后一个bar,可能是不完整的,强制修改
|
||||
if i == bar_len -1 and bar_is_completed:
|
||||
# 根据秒数算的话,要+1,例如13:31,freq=31,第31根bar
|
||||
freq = int((datetime.now() - add_bar.datetime).total_seconds()/60)+1
|
||||
callback(add_bar,False,freq)
|
||||
else:
|
||||
callback(add_bar, bar_is_completed, bar_freq)
|
||||
|
||||
return True,ret_bars
|
||||
|
||||
def download_bars(self, symbol, period, size_=None, start_dt=None):
|
||||
"""
|
||||
返回k线数据
|
||||
symbol:合约
|
||||
period: 周期: 1min,3min,5min,15min,30min,1day,3day,1hour,2hour,4hour,6hour,12hour
|
||||
"""
|
||||
ret_bars = []
|
||||
if symbol not in symbol_list:
|
||||
msg = u'{} {}不在下载清单中'.format(datetime.now(), symbol)
|
||||
if self.strategy:
|
||||
self.strategy.writeCtaError(msg)
|
||||
else:
|
||||
print(msg)
|
||||
return ret_bars
|
||||
|
||||
url = u'https://www.okex.com/api/v1/kline.do?symbol={}&type={}'.format(symbol, period)
|
||||
if isinstance(size_,int):
|
||||
url = url + u'&size={}'.format(size_)
|
||||
if start_dt is not None and isinstance(start_dt,datetime):
|
||||
url = url + u'&since={}'.format(int(start_dt.timestamp()*1000))
|
||||
self.writeLog('{}开始下载:{} {}数据.URL:{}'.format(datetime.now(), symbol, period,url))
|
||||
|
||||
content = None
|
||||
try:
|
||||
content = self.session.get(url).content.decode('gbk')
|
||||
except Exception as ex:
|
||||
self.writeError('exception in get:{},{},{}'.format(url,str(ex), traceback.format_exc()))
|
||||
return ret_bars
|
||||
|
||||
bars = execjs.eval(content)
|
||||
|
||||
if not isinstance(bars,list):
|
||||
self.writeError('返回数据不是list:{}'.format(content))
|
||||
return ret_bars
|
||||
|
||||
for i, bar in enumerate(bars):
|
||||
if len(bar) < 5:
|
||||
self.writeError('error when get bar:{}'.format(bar))
|
||||
return ret_bars
|
||||
if i == 0:
|
||||
continue
|
||||
add_bar = {}
|
||||
try:
|
||||
|
||||
bar_datetime= datetime.fromtimestamp(bar[0] / 1000)
|
||||
add_bar['datetime'] = bar_datetime.strftime('%Y-%m-%d %H:%M:%S')
|
||||
add_bar['date'] = bar_datetime.strftime('%Y-%m-%d')
|
||||
add_bar['time'] = bar_datetime.strftime('%H:%M:%S')
|
||||
add_bar['open'] = float(bar[1])
|
||||
add_bar['high'] = float(bar[2])
|
||||
add_bar['low'] = float(bar[3])
|
||||
add_bar['close'] = float(bar[4])
|
||||
add_bar['volume'] = float(bar[5])
|
||||
except Exception as ex:
|
||||
self.writeError('error when convert bar:{},ex:{},t:{}'.format(bar, str(ex), traceback.format_exc()))
|
||||
|
||||
ret_bars.append(add_bar)
|
||||
|
||||
return ret_bars
|
||||
|
||||
|
||||
class TestStrategy(object):
|
||||
|
||||
def __init__(self):
|
||||
|
||||
self.minDiff = 1
|
||||
self.shortSymbol = 'btc'
|
||||
self.vtSymbol = 'btc'
|
||||
|
||||
self.TMinuteInterval = 1
|
||||
def addBar(self,bar,bar_is_completed, bar_freq):
|
||||
print(u'tradingDay:{},dt:{},{} o:{},h:{},l:{},c:{},v:{}'.format(bar.tradingDay, bar.datetime,bar.vtSymbol, bar.open, bar.high,
|
||||
bar.low, bar.close, bar.volume))
|
||||
def onBar(self, bar):
|
||||
print(u'tradingDay:{},dt:{},{} o:{},h:{},l:{},c:{},v:{}'.format(bar.tradingDay,bar.datetime,bar.vtSymbol, bar.open, bar.high, bar.low, bar.close, bar.volume))
|
||||
|
||||
def writeCtaLog(self, content):
|
||||
print(content)
|
||||
|
||||
def writeCtaError(self, content):
|
||||
print(content)
|
||||
|
||||
if __name__ == '__main__':
|
||||
t = TestStrategy()
|
||||
|
||||
ok_data = OkexData(t)
|
||||
|
||||
# 下载日线
|
||||
#bars = ok_data.download_bars(symbol='btc_usdt', period='1day')
|
||||
# 下载分钟
|
||||
bars = ok_data.download_bars(symbol='btc_usdt', period='1min',start_dt=datetime.strptime('2017-06-01','%Y-%m-%d'))
|
||||
for bar in bars:
|
||||
print(bar['datetime'])
|
||||
|
||||
|
@ -40,7 +40,10 @@ from vnpy.trader.vtFunction import todayDate, getJsonPath
|
||||
from vnpy.trader.util_mail import sendmail
|
||||
# 加载 strategy目录下所有的策略
|
||||
from vnpy.trader.app.ctaStrategy.strategy import STRATEGY_CLASS
|
||||
|
||||
try:
|
||||
from vnpy.trader.util_wechat import *
|
||||
except:
|
||||
print('import util_wechat fail')
|
||||
|
||||
MATRIX_DB_NAME = 'matrix' # 虚拟策略矩阵的数据库名称
|
||||
POSITION_DISPATCH_COLL_NAME = 'position_dispatch' # 虚拟策略矩阵的策略调度配置collection名称
|
||||
@ -148,7 +151,7 @@ class CtaEngine(object):
|
||||
contract = self.mainEngine.getContract(vtSymbol)
|
||||
if contract is None:
|
||||
self.writeCtaError(
|
||||
u'vtEngine.sendOrder取不到{}合约得信息,{}发送{}委托:{},v{}'.format(vtSymbol, strategy.name, orderType, price,
|
||||
u'vtEngine.sendOrder取不到{}合约得信息,{}发送{}委托:{},v{}失败'.format(vtSymbol, strategy.name, orderType, price,
|
||||
volume))
|
||||
return ''
|
||||
|
||||
@ -256,12 +259,18 @@ class CtaEngine(object):
|
||||
|
||||
if strategy:
|
||||
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
|
||||
|
||||
self.writeCtaLog(u'策略%s发送委托,%s, %s,%s,%s@%s'
|
||||
% (strategy.name, vtSymbol, req.offset, req.direction, volume, price))
|
||||
msg = u'策略%s发送委托,%s, %s,%s,%s@%s' % (strategy.name, vtSymbol, req.offset, req.direction, volume, price)
|
||||
self.writeCtaLog(msg)
|
||||
else:
|
||||
self.writeCtaLog(u'%s发送委托,%s, %s,%s,%s@%s'
|
||||
% ('CtaEngine', vtSymbol, req.offset, req.direction, volume, price))
|
||||
msg = u'%s发送委托,%s, %s,%s,%s@%s' % ('CtaEngine', vtSymbol, req.offset, req.direction, volume, price)
|
||||
self.writeCtaLog(msg)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
|
||||
return vtOrderID
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -283,6 +292,13 @@ class CtaEngine(object):
|
||||
req.sessionID = order.sessionID
|
||||
req.orderID = order.orderID
|
||||
self.mainEngine.cancelOrder(req, order.gatewayName)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
msg = u'发送撤单指令,%s, %s,%s' % (order.symbol, order.orderID, order.gatewayName)
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
else:
|
||||
if order.status == STATUS_ALLTRADED:
|
||||
self.writeCtaLog(u'委托单({0}已执行,无法撤销'.format(vtOrderID))
|
||||
@ -326,6 +342,13 @@ class CtaEngine(object):
|
||||
order.totalVolume - order.tradedVolume))
|
||||
self.mainEngine.cancelOrder(req, order.gatewayName)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
msg = u'撤销所有单,{}'.format(symbol)
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def sendStopOrder(self, vtSymbol, orderType, price, volume, strategy):
|
||||
"""发停止单(本地实现)"""
|
||||
@ -361,10 +384,14 @@ class CtaEngine(object):
|
||||
self.stopOrderDict[stopOrderID] = so # 字典中不会删除
|
||||
self.workingStopOrderDict[stopOrderID] = so # 字典中会删除
|
||||
|
||||
self.writeCtaLog(u'发停止单成功,'
|
||||
u'Id:{0},Symbol:{1},Type:{2},Price:{3},Volume:{4}'
|
||||
u'.'.format(stopOrderID, vtSymbol, orderType, price, volume))
|
||||
msg = u'发停止单成功,Id:{},Symbol:{},Type:{},Price:{},Volume:{}'.format(stopOrderID, vtSymbol, orderType, price, volume)
|
||||
self.writeCtaLog(msg)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
return stopOrderID
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -379,9 +406,21 @@ class CtaEngine(object):
|
||||
so.status = STOPORDER_CANCELLED # STOPORDER_WAITING =》STOPORDER_CANCELLED
|
||||
del self.workingStopOrderDict[stopOrderID] # 删除
|
||||
self.writeCtaLog(u'撤销停止单:{0}成功.'.format(stopOrderID))
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(u'撤销停止单:{0}成功.'.format(stopOrderID), target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
return True
|
||||
else:
|
||||
self.writeCtaLog(u'撤销停止单:{0}失败,不存在Id.'.format(stopOrderID))
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(u'撤销停止单:{0}失败,不存在Id.'.format(stopOrderID), target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
return False
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -441,11 +480,13 @@ class CtaEngine(object):
|
||||
ctaTick = CtaTickData()
|
||||
d = ctaTick.__dict__
|
||||
for key in d.keys():
|
||||
d[key] = tick.__getattribute__(key)
|
||||
if key in tick.__dict__:
|
||||
d[key] = tick.__getattribute__(key)
|
||||
|
||||
if not ctaTick.datetime:
|
||||
# 添加datetime字段
|
||||
ctaTick.datetime = datetime.strptime(' '.join([tick.date, tick.time]), '%Y-%m-%d %H:%M:%S.%f')
|
||||
tickDate = tick.date.replace('-', '')
|
||||
ctaTick.datetime = datetime.strptime(' '.join([tickDate, tick.time]), '%Y%m%d %H:%M:%S.%f')
|
||||
|
||||
# 逐个推送到策略实例中
|
||||
l = self.tickStrategyDict[tick.vtSymbol]
|
||||
@ -735,6 +776,26 @@ class CtaEngine(object):
|
||||
pass
|
||||
self.mainEngine.writeCritical(content)
|
||||
|
||||
def sendAlertToWechat(self,content,target):
|
||||
"""发送微信告警"""
|
||||
gw = EMPTY_STRING
|
||||
if len(self.mainEngine.connected_gw_names)>0:
|
||||
gw = self.mainEngine.connected_gw_names[0]
|
||||
else:
|
||||
if len(self.mainEngine.gatewayDetailList) > 0:
|
||||
d = self.mainEngine.gatewayDetailList[0]
|
||||
if isinstance(d, dict):
|
||||
gw = d.get('gatewayDisplayName','Gateway')
|
||||
|
||||
if len(gw)>0:
|
||||
content = u'[gw:{}]{}'.format(gw,content)
|
||||
try:
|
||||
from vnpy.trader import util_wechat
|
||||
self.writeCtaLog(u'发送微信通知:{}'.format(content))
|
||||
util_wechat.sendWeChatMsg(content=content, target=target,level=util_wechat.WECHAT_LEVEL_DEBUG)
|
||||
except Exception as ex:
|
||||
self.writeCtaError(u'调用微信接口失败:{} {}'.format(str(ex), traceback.format_exc()))
|
||||
|
||||
def sendCtaSignal(self, source, symbol, direction, price, level):
|
||||
"""发出交易信号"""
|
||||
s = VtSignalData()
|
||||
@ -850,8 +911,8 @@ class CtaEngine(object):
|
||||
self.writeCtaLog(u'撤销运行中策略{}的强制清仓,恢复运行'.format(name))
|
||||
return False
|
||||
except Exception as ex:
|
||||
self.writeCtaCritical(u'撤销运行中策略{}的强制清仓时异常:{}'.format(name, str(ex)))
|
||||
traceback.print_exc()
|
||||
self.writeCtaCritical(u'撤销运行中策略{}的强制清仓时异常:{},{}'.format(name, str(ex),traceback.format_exc()))
|
||||
|
||||
return False
|
||||
else:
|
||||
# 防止策略重名
|
||||
@ -921,13 +982,21 @@ class CtaEngine(object):
|
||||
# 自动初始化
|
||||
if 'auto_init' in setting:
|
||||
if setting['auto_init'] == True:
|
||||
self.writeCtaLog(u'自动初始化策略')
|
||||
self.initStrategy(name=name)
|
||||
self.writeCtaLog(u'自动初始化策略:{}'.format(name))
|
||||
try:
|
||||
self.initStrategy(name=name)
|
||||
except Exception as ex:
|
||||
self.writeCtaCritical(u'初始化策略:{} 异常,{},{}'.format(name,str(ex),traceback.format_exc()))
|
||||
return False
|
||||
|
||||
if 'auto_start' in setting:
|
||||
if setting['auto_start'] == True:
|
||||
self.writeCtaLog(u'自动启动策略')
|
||||
self.startStrategy(name=name)
|
||||
self.writeCtaLog(u'自动启动策略:{}'.format(name))
|
||||
try:
|
||||
self.startStrategy(name=name)
|
||||
except Exception as ex:
|
||||
self.writeCtaCritical(u'自动启动策略:{} 异常,{},{}'.format(name, str(ex), traceback.format_exc()))
|
||||
return False
|
||||
return True
|
||||
|
||||
def initStrategy(self, name, force=False):
|
||||
@ -1593,7 +1662,7 @@ class CtaEngine(object):
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
with open(self.settingfilePath) as f:
|
||||
with open(self.settingfilePath,'r',encoding='UTF-8') as f:
|
||||
l = json.load(f)
|
||||
for setting in l:
|
||||
try:
|
||||
@ -1761,9 +1830,13 @@ class CtaEngine(object):
|
||||
|
||||
# 发出日志
|
||||
content =u'策略{}触发异常已停止.{}'.format(strategy.name,traceback.format_exc())
|
||||
self.writeCtaLog(content)
|
||||
self.writeCtaError(content)
|
||||
self.mainEngine.writeCritical(content)
|
||||
|
||||
if hasattr(strategy,'backtesting') and hasattr(strategy,'wechat_source'):
|
||||
if not strategy.backtesting and len(strategy.wechat_source)>0:
|
||||
self.sendAlertToWechat(content=content,target=strategy.wechat_source)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# 仓位持久化相关
|
||||
def savePosition(self):
|
||||
@ -2047,7 +2120,14 @@ class PositionBuffer(object):
|
||||
self.shortYd = EMPTY_INT
|
||||
|
||||
self.frozen = EMPTY_FLOAT
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def toStr(self):
|
||||
"""更新显示信息"""
|
||||
str = u'long:{},yd:{},td:{}, short:{},yd:{},td:{}, fz:{};' \
|
||||
.format(self.longPosition, self.longYd, self.longToday,
|
||||
self.shortPosition, self.shortYd, self.shortToday,self.frozen)
|
||||
return str
|
||||
#----------------------------------------------------------------------
|
||||
def updatePositionData(self, pos):
|
||||
"""更新持仓数据"""
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,7 +26,7 @@ PERIOD_MINUTE = 'minute' # 分钟级别周期
|
||||
PERIOD_HOUR = 'hour' # 小时级别周期
|
||||
PERIOD_DAY = 'day' # 日级别周期
|
||||
|
||||
def getCtaBarByType(bar_type):
|
||||
def getCtaBarClass(bar_type):
|
||||
assert isinstance(bar_type,str)
|
||||
if bar_type == PERIOD_SECOND:
|
||||
return CtaLineBar
|
||||
@ -39,6 +39,7 @@ def getCtaBarByType(bar_type):
|
||||
|
||||
raise Exception('no matched CTA bar type:{}'.format(bar_type))
|
||||
|
||||
|
||||
class CtaLineBar(object):
|
||||
"""CTA K线"""
|
||||
""" 使用方法:
|
||||
@ -125,6 +126,8 @@ class CtaLineBar(object):
|
||||
self.lastTick = None
|
||||
self.curTradingDay = EMPTY_STRING
|
||||
|
||||
self.cur_price = EMPTY_FLOAT
|
||||
|
||||
# K线保存数据
|
||||
self.bar = None # K线数据对象
|
||||
self.lineBar = [] # K线缓存数据队列
|
||||
@ -472,16 +475,18 @@ class CtaLineBar(object):
|
||||
self.writeCtaLog(u'竞价排名tick时间:{0}'.format(tick.datetime))
|
||||
return
|
||||
|
||||
self.curTick = tick
|
||||
self.curTick = copy.copy(tick)
|
||||
if self.curTick.lastPrice is None or self.curTick.lastPrice == 0:
|
||||
self.curTick.lastPrice = (self.curTick.askPrice1 + self.curTick.bidPrice1) / 2
|
||||
self.cur_price = (self.curTick.askPrice1 + self.curTick.bidPrice1) / 2
|
||||
else:
|
||||
self.cur_price = self.curTick.lastPrice
|
||||
|
||||
# 3.生成x K线,若形成新Bar,则触发OnBar事件
|
||||
self.drawLineBar(tick)
|
||||
|
||||
# 更新curPeriod的High,low
|
||||
if self.curPeriod is not None:
|
||||
if self.curTick.lastPrice is None:
|
||||
self.curTick.lastPrice = (self.curTick.askPrice1 + self.curTick.bidPrice1) / 2
|
||||
|
||||
self.curPeriod.onPrice(self.curTick.lastPrice)
|
||||
|
||||
# 4.执行 bar内计算
|
||||
@ -498,6 +503,9 @@ class CtaLineBar(object):
|
||||
"""
|
||||
l1 = len(self.lineBar)
|
||||
|
||||
# 更新最后价格
|
||||
self.cur_price = bar.close
|
||||
|
||||
if l1 == 0:
|
||||
new_bar = copy.copy(bar)
|
||||
self.lineBar.append(new_bar)
|
||||
@ -2696,13 +2704,13 @@ class CtaLineBar(object):
|
||||
self.skd_last_cross = (self.lineSK[-1] + self.lineSK[-2] + self.lineSD[-1] + self.lineSD[-2])/4
|
||||
self.skd_rt_count = self.skd_count
|
||||
self.skd_rt_last_cross = self.skd_last_cross
|
||||
if self.skd_rt_cross_price == 0 or self.lineBar[-1].close < self.skd_rt_cross_price:
|
||||
self.skd_rt_cross_price = self.lineBar[-1].close
|
||||
self.skd_cross_price = min(self.lineBar[-1].close ,self.skd_rt_cross_price)
|
||||
if self.skd_rt_cross_price == 0 or self.cur_price < self.skd_rt_cross_price:
|
||||
self.skd_rt_cross_price = self.cur_price
|
||||
self.skd_cross_price = self.cur_price
|
||||
if self.skd_divergence < 0:
|
||||
# 若原来是顶背离,消失
|
||||
self.skd_divergence = 0
|
||||
|
||||
self.writeCtaLog(u'{} Gold Cross:{} at {}'.format(self.name, self.skd_last_cross, self.skd_cross_price))
|
||||
else: #if self.lineSK[-1] < self.lineSK[-2]:
|
||||
# 延续死叉
|
||||
self.skd_count -= 1
|
||||
@ -2722,14 +2730,16 @@ class CtaLineBar(object):
|
||||
self.skd_last_cross = (self.lineSK[-1] + self.lineSK[-2] + self.lineSD[-1] + self.lineSD[-2]) / 4
|
||||
self.skd_rt_count = self.skd_count
|
||||
self.skd_rt_last_cross = self.skd_last_cross
|
||||
if self.skd_rt_cross_price == 0 or self.lineBar[-1].close > self.skd_rt_cross_price:
|
||||
self.skd_rt_cross_price = self.lineBar[-1].close
|
||||
self.skd_cross_price = max(self.lineBar[-1].close, self.skd_rt_cross_price)
|
||||
if self.skd_rt_cross_price == 0 or self.cur_price > self.skd_rt_cross_price:
|
||||
self.skd_rt_cross_price = self.cur_price
|
||||
self.skd_cross_price = self.cur_price
|
||||
|
||||
# 若原来是底背离,消失
|
||||
if self.skd_divergence > 0:
|
||||
self.skd_divergence = 0
|
||||
|
||||
self.writeCtaLog(u'{} Dead Cross:{} at {}'.format(self.name, self.skd_last_cross, self.skd_cross_price))
|
||||
|
||||
else: #if self.lineSK[-1] > self.lineSK[-2]:
|
||||
# 延续金叉
|
||||
self.skd_count += 1
|
||||
@ -2909,7 +2919,9 @@ class CtaLineBar(object):
|
||||
if self.skd_rt_count >= 0:
|
||||
self.skd_rt_count = -1
|
||||
self.skd_rt_last_cross = skd_last_cross
|
||||
self.skd_rt_cross_price = self.lineBar[-1].close
|
||||
self.skd_rt_cross_price = self.cur_price
|
||||
self.writeCtaLog(u'{} rt Dead Cross at:{} ,price:{}'
|
||||
.format(self.name, self.skd_rt_last_cross, self.skd_rt_cross_price))
|
||||
|
||||
if skd_last_cross > high_skd:
|
||||
return True
|
||||
@ -2942,8 +2954,9 @@ class CtaLineBar(object):
|
||||
if self.skd_rt_count <=0:
|
||||
self.skd_rt_count = 1
|
||||
self.skd_rt_last_cross = skd_last_cross
|
||||
self.skd_rt_cross_price = self.lineBar[-1].close
|
||||
|
||||
self.skd_rt_cross_price = self.cur_price
|
||||
self.writeCtaLog(u'{} rt Gold Cross at:{} ,price:{}'
|
||||
.format(self.name, self.skd_rt_last_cross,self.skd_rt_cross_price))
|
||||
if skd_last_cross < low_skd:
|
||||
return True
|
||||
|
||||
@ -3116,6 +3129,82 @@ class CtaLineBar(object):
|
||||
return None
|
||||
return None
|
||||
|
||||
def is_shadow_line(self,open, high, low, close, direction, shadow_rate, wave_rate):
|
||||
"""
|
||||
是否上影线/下影线
|
||||
:param open: 开仓价
|
||||
:param high: 最高价
|
||||
:param low: 最低价
|
||||
:param close: 收盘价
|
||||
:param direction: 方向(多/空)
|
||||
:param shadown_rate: 上影线比例(百分比)
|
||||
:param wave_rate:振幅(百分比)
|
||||
:return:
|
||||
"""
|
||||
if close<=0 or high <= low or shadow_rate <=0 or wave_rate <=0:
|
||||
self.writeCtaLog(u'是否上下影线,参数出错.close={}, high={},low={},shadow_rate={},wave_rate={}'
|
||||
.format(close, high, low, shadow_rate, wave_rate))
|
||||
return False
|
||||
|
||||
# 振幅 = 高-低 / 收盘价 百分比
|
||||
cur_wave_rate = round(100 * float((high - low) / close), 2)
|
||||
|
||||
# 上涨时,判断上影线
|
||||
if direction == DIRECTION_LONG:
|
||||
# 上影线比例 = 上影线(高- max(开盘,收盘))/ 当日振幅=(高-低)
|
||||
cur_shadow_rate = round(100 * float((high - max(open,close)) / (high-low)),2)
|
||||
if cur_wave_rate >= wave_rate and cur_shadow_rate >= shadow_rate:
|
||||
return True
|
||||
|
||||
# 下跌时,判断下影线
|
||||
elif direction == DIRECTION_SHORT:
|
||||
cur_shadow_rate = round(100 * float((min(open,close)-low) / (high-low)),2)
|
||||
if cur_wave_rate >= wave_rate and cur_shadow_rate >= shadow_rate:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def is_end_tick(self, tick_dt):
|
||||
"""
|
||||
根据短合约和时间,判断是否为最后一个tick
|
||||
:param tick_dt:
|
||||
:return:
|
||||
"""
|
||||
if self.is_7x24:
|
||||
return False
|
||||
|
||||
# 中金所,只有11:30 和15:15,才有最后一个tick
|
||||
if self.shortSymbol in MARKET_ZJ:
|
||||
if (tick_dt.hour == 11 and tick_dt.minute == 30) or (tick_dt.hour == 15 and tick_dt.minute == 15):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
# 其他合约(上期所/郑商所/大连)
|
||||
if 2 <= tick_dt.hour < 23:
|
||||
if (tick_dt.hour == 10 and tick_dt.minute == 15) \
|
||||
or (tick_dt.hour == 11 and tick_dt.minute == 30) \
|
||||
or (tick_dt.hour == 15 and tick_dt.minute == 00) \
|
||||
or (tick_dt.hour == 2 and tick_dt.minute == 30):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
# 夜盘1:30收盘
|
||||
if self.shortSymbol in NIGHT_MARKET_SQ2 and tick_dt.hour == 1 and tick_dt.minute == 00:
|
||||
return True
|
||||
|
||||
# 夜盘23:00收盘
|
||||
if self.shortSymbol in NIGHT_MARKET_SQ3 and tick_dt.hour == 23 and tick_dt.minute == 00:
|
||||
return True
|
||||
|
||||
# 夜盘23:30收盘
|
||||
if self.shortSymbol in NIGHT_MARKET_ZZ or self.shortSymbol in NIGHT_MARKET_DL:
|
||||
if tick_dt.hour == 23 and tick_dt.minute == 30:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
class CtaMinuteBar(CtaLineBar):
|
||||
"""
|
||||
分钟级别K线
|
||||
@ -3209,6 +3298,9 @@ class CtaMinuteBar(CtaLineBar):
|
||||
if bar.tradingDay is None:
|
||||
bar.tradingDay = self.getTradingDate(bar.datetime)
|
||||
|
||||
# 更新最后价格
|
||||
self.cur_price = bar.close
|
||||
|
||||
l1 = len(self.lineBar)
|
||||
|
||||
if l1 == 0:
|
||||
@ -3489,6 +3581,9 @@ class CtaHourBar(CtaLineBar):
|
||||
if bar.tradingDay is None:
|
||||
bar.tradingDay = self.getTradingDate(bar.datetime)
|
||||
|
||||
# 更新最后价格
|
||||
self.cur_price = bar.close
|
||||
|
||||
l1 = len(self.lineBar)
|
||||
|
||||
if l1 == 0:
|
||||
@ -3567,7 +3662,6 @@ class CtaHourBar(CtaLineBar):
|
||||
endtick = False
|
||||
if not self.is_7x24:
|
||||
# 处理日内的间隔时段最后一个tick,如10:15分,11:30分,15:00 和 2:30分
|
||||
|
||||
if (tick.datetime.hour == 10 and tick.datetime.minute == 15) \
|
||||
or (tick.datetime.hour == 11 and tick.datetime.minute == 30) \
|
||||
or (tick.datetime.hour == 15 and tick.datetime.minute == 00) \
|
||||
@ -3590,10 +3684,22 @@ class CtaHourBar(CtaLineBar):
|
||||
lastBar = self.lineBar[-1]
|
||||
is_new_bar = False
|
||||
|
||||
if self.last_minute is None:
|
||||
if tick.datetime.second == 0:
|
||||
self.m1_bars_count += 1
|
||||
self.last_minute = tick.datetime.minute
|
||||
|
||||
# 不在同一交易日,推入新bar
|
||||
if self.curTradingDay != tick.tradingDay:
|
||||
is_new_bar = True
|
||||
# 去除分钟和秒数
|
||||
tick.datetime = datetime.strptime(tick.datetime.strftime('%Y-%m-%d %H:00:00'), '%Y-%m-%d %H:%M:%S')
|
||||
tick.time = tick.datetime.strftime('%H:%M:%S')
|
||||
self.curTradingDay = tick.tradingDay
|
||||
self.writeCtaLog('{} drawLineBar() new_bar,{} curTradingDay:{},tick.tradingDay:{}'
|
||||
.format(self.name, tick.datetime.strftime("%Y-%m-%d %H:%M:%S"), self.curTradingDay,
|
||||
tick.tradingDay))
|
||||
|
||||
else:
|
||||
# 同一交易日,看分钟是否一致
|
||||
if tick.datetime.minute != self.last_minute and not endtick:
|
||||
@ -3602,14 +3708,27 @@ class CtaHourBar(CtaLineBar):
|
||||
|
||||
if self.is_7x24:
|
||||
if (tick.datetime - lastBar.datetime).total_seconds() >= 3600 * self.barTimeInterval:
|
||||
self.writeCtaLog('{} drawLineBar() new_bar,{} - {} > 3600 * {} '
|
||||
.format(self.name, tick.datetime.strftime("%Y-%m-%d %H:%M:%S"), lastBar.datetime.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
self.barTimeInterval))
|
||||
is_new_bar = True
|
||||
if len(tick.tradingDay) >0:
|
||||
# 去除分钟和秒数
|
||||
tick.datetime = datetime.strptime(tick.datetime.strftime('%Y-%m-%d %H:00:00'), '%Y-%m-%d %H:%M:%S')
|
||||
tick.time = tick.datetime.strftime('%H:%M:%S')
|
||||
if len(tick.tradingDay) > 0:
|
||||
self.curTradingDay = tick.tradingDay
|
||||
else:
|
||||
self.curTradingDay = tick.date
|
||||
|
||||
if self.m1_bars_count > 60 * self.barTimeInterval:
|
||||
self.writeCtaLog('{} drawLineBar() new_bar,{} {} > 60 * {} '
|
||||
.format(self.name, tick.datetime.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
self.m1_bars_count,
|
||||
self.barTimeInterval))
|
||||
is_new_bar = True
|
||||
# 去除秒数
|
||||
tick.datetime = datetime.strptime(tick.datetime.strftime('%Y-%m-%d %H:%M:00'), '%Y-%m-%d %H:%M:%S')
|
||||
tick.time = tick.datetime.strftime('%H:%M:%S')
|
||||
|
||||
if is_new_bar:
|
||||
# 创建并推入新的Bar
|
||||
@ -3741,6 +3860,9 @@ class CtaDayBar(CtaLineBar):
|
||||
:param bar_freq, bar对象得frequency
|
||||
:return:
|
||||
"""
|
||||
# 更新最后价格
|
||||
self.cur_price = bar.close
|
||||
|
||||
l1 = len(self.lineBar)
|
||||
|
||||
if l1 == 0:
|
||||
|
@ -80,8 +80,6 @@ class BinanceGateway(VtGateway):
|
||||
self.writeLog(u'BINANCE连接配置缺少字段,请检查')
|
||||
return
|
||||
|
||||
|
||||
|
||||
self.api_spot.active = True
|
||||
|
||||
if self.log_message:
|
||||
@ -96,13 +94,15 @@ class BinanceGateway(VtGateway):
|
||||
sub.symbol = symbol_pair
|
||||
self.subscribe(sub)
|
||||
|
||||
|
||||
self.writeLog(u'{}接口初始化成功'.format(self.gatewayName))
|
||||
|
||||
# 启动查询
|
||||
self.initQuery()
|
||||
self.startQuery()
|
||||
|
||||
def checkStatus(self):
|
||||
return self.connected and self.api_spot.checkStatus()
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def subscribe(self, subscribeReq):
|
||||
"""订阅行情,自动订阅全部行情,无需实现"""
|
||||
@ -116,7 +116,7 @@ class BinanceGateway(VtGateway):
|
||||
except Exception as ex:
|
||||
self.writeError(u'send order Exception:{},{}'.format(str(ex),traceback.format_exc()))
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def cancelOrder(self, cancelOrderReq):
|
||||
"""撤单"""
|
||||
return self.api_spot.cancel(cancelOrderReq)
|
||||
@ -418,6 +418,23 @@ print ex.status_code, ex.message , ex.code , ex.request , ex.uri , ex.kwargs
|
||||
|
||||
self.gateway.onContract(contract)
|
||||
|
||||
def checkStatus(self):
|
||||
"""
|
||||
检查接口状态:
|
||||
若active为False,return False
|
||||
若active为True,检查ticker得更新时间
|
||||
:return:
|
||||
"""
|
||||
if not self.active:
|
||||
return False
|
||||
|
||||
if len(self.tickDict.items())>0:
|
||||
symbol,last_tick = list(self.tickDict.items())[0]
|
||||
if last_tick.datetime and (datetime.now()-last_tick.datetime).total_seconds() > 60:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onAllTicker(self,msg):
|
||||
"""币安支持所有 ticker 同时socket过来"""
|
||||
@ -459,6 +476,8 @@ print ex.status_code, ex.message , ex.code , ex.request , ex.uri , ex.kwargs
|
||||
tick.askPrice5, tick.askVolume5 = [0 , 0]
|
||||
|
||||
tick.datetime , tick.date , tick.time = self.generateDateTime( float(msg["E"]))
|
||||
utc_dt = datetime.utcfromtimestamp( float(msg["E"])/1e3)
|
||||
tick.tradingDay = utc_dt.strftime('%Y-%m-%d')
|
||||
self.gateway.onTick(tick)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -630,7 +649,8 @@ print ex.status_code, ex.message , ex.code , ex.request , ex.uri , ex.kwargs
|
||||
self.gateway.writeLog(u'OnDepth {}'.format(traceback.format_exc()))
|
||||
|
||||
tick.datetime , tick.date, tick.time = self.generateDateTime(uu_time_stamp)
|
||||
|
||||
utc_dt = datetime.utcfromtimestamp(float(uu_time_stamp)/ 1e3)
|
||||
tick.tradingDay = utc_dt.strftime('%Y-%m-%d')
|
||||
# print tick.__dict__
|
||||
self.gateway.onTick(tick)
|
||||
#self.gateway.onTick(copy(tick))
|
||||
@ -773,6 +793,10 @@ print ex.status_code, ex.message , ex.code , ex.request , ex.uri , ex.kwargs
|
||||
'''
|
||||
#----------------------------------------------------------------------
|
||||
def onGetAccount(self, data, req, reqID):
|
||||
|
||||
if self.gateway and not self.gateway.connected:
|
||||
self.gateway.connected = True
|
||||
|
||||
balances = data["balances"]
|
||||
account = VtAccountData()
|
||||
account.gatewayName = self.gatewayName
|
||||
@ -1114,5 +1138,5 @@ BREAK
|
||||
"""生成时间"""
|
||||
dt = datetime.fromtimestamp(float(s)/1e3)
|
||||
time = dt.strftime("%H:%M:%S.%f")
|
||||
date = dt.strftime("%Y%m%d")
|
||||
date = dt.strftime("%Y-%m-%d")
|
||||
return dt , date, time
|
||||
|
@ -920,7 +920,7 @@ class OkexSpotApi(WsSpotApi):
|
||||
|
||||
tick.date, tick.time,tick.datetime = self.generateDateTime(data['timestamp'])
|
||||
# print "Depth", tick.date, tick.time
|
||||
|
||||
tick.tradingDay = tick.date
|
||||
# 推送tick事件
|
||||
newtick = copy(tick)
|
||||
self.gateway.onTick(newtick)
|
||||
|
Loading…
Reference in New Issue
Block a user