update
This commit is contained in:
parent
22180cf239
commit
17d908ab56
@ -26,7 +26,8 @@ class arbTemplate(object):
|
||||
base_symbol = EMPTY_STRING # 交易主货币 btc
|
||||
quote_symbol = EMPTY_STRING # 基准货币 usdt
|
||||
spot_symbol = EMPTY_STRING # 现货交易所币对 btc_usdt
|
||||
future_symbol = EMPTY_STRING # 期货合约 btc:next_week:10
|
||||
future_symbol = EMPTY_STRING # 期货合约 btc:next_week:10
|
||||
future_net_symbol = EMPTY_STRING # 合约账号内的期货合约净仓symbol btc.[future]
|
||||
Leg1Symbol = EMPTY_STRING # 带交易所信息的symbol,如: btc_usdt.OKEX
|
||||
Leg2Symbol = EMPTY_STRING # 带交易所信息的symbol,如: btc:next_week:10.OKEX
|
||||
exchange = EMPTY_STRING
|
||||
@ -46,6 +47,7 @@ class arbTemplate(object):
|
||||
'quote_symbol',
|
||||
'spot_symbol',
|
||||
'future_symbol',
|
||||
'future_net_symbol',
|
||||
'Leg1Symbol',
|
||||
'Leg2Symbol',
|
||||
'exchange',
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -56,7 +56,7 @@ ENGINETYPE_TRADING = 'trading' # 实盘
|
||||
|
||||
|
||||
# CTA引擎中涉及的数据类定义
|
||||
from vnpy.trader.vtConstant import *
|
||||
from vnpy.trader.vtConstant import EMPTY_STRING,EMPTY_UNICODE,EMPTY_FLOAT,EMPTY_INT,COLOR_EQUAL
|
||||
|
||||
########################################################################
|
||||
class StopOrder(object):
|
||||
|
@ -266,10 +266,10 @@ class CtaEngine(object):
|
||||
self.writeCtaLog(msg)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
#try:
|
||||
# sendWeChatMsg(msg, target=self.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
#except:
|
||||
# pass
|
||||
|
||||
return vtOrderID
|
||||
|
||||
@ -294,11 +294,11 @@ class CtaEngine(object):
|
||||
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
|
||||
#try:
|
||||
# msg = u'发送撤单指令,%s, %s,%s' % (order.symbol, order.orderID, order.gatewayName)
|
||||
# sendWeChatMsg(msg, target=self.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
#except:
|
||||
# pass
|
||||
else:
|
||||
if order.status == STATUS_ALLTRADED:
|
||||
self.writeCtaLog(u'委托单({0}已执行,无法撤销'.format(vtOrderID))
|
||||
@ -343,11 +343,11 @@ class CtaEngine(object):
|
||||
self.mainEngine.cancelOrder(req, order.gatewayName)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
msg = u'撤销所有单,{}'.format(symbol)
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
#try:
|
||||
# msg = u'撤销所有单,{}'.format(symbol)
|
||||
# sendWeChatMsg(msg, target=self.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
#except:
|
||||
# pass
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def sendStopOrder(self, vtSymbol, orderType, price, volume, strategy):
|
||||
@ -388,10 +388,10 @@ class CtaEngine(object):
|
||||
self.writeCtaLog(msg)
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(msg, target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
#try:#
|
||||
# sendWeChatMsg(msg, target=self.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
#except:
|
||||
# pass
|
||||
return stopOrderID
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
@ -408,19 +408,19 @@ class CtaEngine(object):
|
||||
self.writeCtaLog(u'撤销停止单:{0}成功.'.format(stopOrderID))
|
||||
|
||||
# 发送微信
|
||||
try:
|
||||
sendWeChatMsg(u'撤销停止单:{0}成功.'.format(stopOrderID), target=self.ctaEngine.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
except:
|
||||
pass
|
||||
#try:
|
||||
# sendWeChatMsg(u'撤销停止单:{0}成功.'.format(stopOrderID), target=self.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
|
||||
#try:
|
||||
# sendWeChatMsg(u'撤销停止单:{0}失败,不存在Id.'.format(stopOrderID), target=self.mainEngine.gatewayDetailList[0]['gatewayName'])
|
||||
#except:
|
||||
# pass
|
||||
return False
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
|
@ -1,4 +1,4 @@
|
||||
# encoding: UTF-8
|
||||
# encoding: UTF-8
|
||||
|
||||
import json
|
||||
import os
|
||||
@ -9,5 +9,5 @@ from vnpy.trader.app.ctaStrategy.language.chinese import text
|
||||
|
||||
# 是否要使用英文
|
||||
from vnpy.trader.vtGlobal import globalSetting
|
||||
if globalSetting['language'] == 'english':
|
||||
if len(globalSetting) > 0 and globalSetting['language'] == 'english':
|
||||
from vnpy.trader.app.ctaStrategy.language.english import text
|
@ -1,20 +1,42 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
'''
|
||||
动态载入所有的策略类
|
||||
动态载入所有的策略类,先从vnpy/trader/app/ctaStrategy/strategy下加载,其次,从工作目录下strategy加载。
|
||||
如果重复,工作目录的strategy优先。
|
||||
'''
|
||||
|
||||
import os
|
||||
import importlib
|
||||
|
||||
import traceback
|
||||
|
||||
# 用来保存策略类的字典
|
||||
STRATEGY_CLASS = {}
|
||||
|
||||
# 获取目录路径
|
||||
# ----------------------------------------------------------------------
|
||||
def loadStrategyModule(moduleName):
|
||||
"""使用importlib动态载入模块"""
|
||||
try:
|
||||
print('loading {0}'.format(moduleName))
|
||||
module = importlib.import_module(moduleName)
|
||||
|
||||
# 遍历模块下的对象,只有名称中包含'Strategy'的才是策略类
|
||||
for k in dir(module):
|
||||
if 'Strategy' in k:
|
||||
print('adding {} into STRATEGY_CLASS'.format(k))
|
||||
v = module.__getattribute__(k)
|
||||
if k in STRATEGY_CLASS:
|
||||
print('Replace strategy {} with {}'.format(k,moduleName))
|
||||
STRATEGY_CLASS[k] = v
|
||||
except Exception as ex:
|
||||
print('-' * 20)
|
||||
print('Failed to import strategy file %s:' % moduleName)
|
||||
print('Exception:{},{}'.format(str(ex),traceback.format_exc()))
|
||||
|
||||
# 获取目录路径
|
||||
path = os.path.abspath(os.path.dirname(__file__))
|
||||
|
||||
print ('init {0}'.format(path))
|
||||
print('init strategies from {}'.format(path))
|
||||
|
||||
# 遍历strategy目录下的文件
|
||||
for root, subdirs, files in os.walk(path):
|
||||
@ -23,19 +45,20 @@ for root, subdirs, files in os.walk(path):
|
||||
if 'strategy' in name and '.pyc' not in name:
|
||||
# 模块名称需要上前缀
|
||||
moduleName = 'vnpy.trader.app.ctaStrategy.strategy.' + name.replace('.py', '')
|
||||
print ('loading {0}'.format(moduleName))
|
||||
try:
|
||||
# 使用importlib动态载入模块
|
||||
module = importlib.import_module(moduleName)
|
||||
except Exception as ex:
|
||||
print ('load fail,excepion:{0}'.format(ex))
|
||||
continue
|
||||
loadStrategyModule(moduleName)
|
||||
|
||||
# 遍历模块下的对象,只有名称中包含'Strategy'的才是策略类
|
||||
for k in dir(module):
|
||||
if 'Strategy' in k:
|
||||
print ('adding {0} into STRATEGY_CLASS'.format(k))
|
||||
v = module.__getattribute__(k)
|
||||
STRATEGY_CLASS[k] = v
|
||||
|
||||
print( 'finished load strategy modules')
|
||||
# 遍历工作目录下的文件
|
||||
#stratey_working_path = os.path.abspath(os.path.join(os.getcwd(), 'strategy'))
|
||||
#
|
||||
#if os.path.exists(stratey_working_path):
|
||||
# print('init strategies from {}'.format(stratey_working_path))
|
||||
# for root, subdirs, files in os.walk(stratey_working_path):
|
||||
# for name in files:
|
||||
# # 只有文件名中包含strategy且非.pyc的文件,才是策略文件
|
||||
# if 'strategy' in name and '.pyc' not in name:
|
||||
# # 模块名称无需前缀
|
||||
# moduleName = name.replace('.py', '')
|
||||
# loadStrategyModule(moduleName)
|
||||
#
|
||||
print('finished load strategy modules')
|
||||
|
@ -496,7 +496,7 @@ class SniperAlgo(StAlgoTemplate):
|
||||
#----------------------------------------------------------------------
|
||||
def cancelAllOrders(self):
|
||||
"""撤销全部委托"""
|
||||
for orderList in self.legOrderDict.values():
|
||||
for orderList in list(self.legOrderDict.values()):
|
||||
for vtOrderID in orderList:
|
||||
self.algoEngine.cancelOrder(vtOrderID)
|
||||
|
||||
|
@ -274,7 +274,7 @@ class StDataEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def getAllSpreads(self):
|
||||
"""获取所有的价差"""
|
||||
return self.spreadDict.values()
|
||||
return list(self.spreadDict.values())
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -343,7 +343,7 @@ class StAlgoEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def processTimerEvent(self, event):
|
||||
""""""
|
||||
for algo in self.algoDict.values():
|
||||
for algo in list(self.algoDict.values()):
|
||||
algo.updateTimer()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -450,7 +450,7 @@ class StAlgoEngine(object):
|
||||
def saveSetting(self):
|
||||
"""保存算法配置"""
|
||||
setting = {}
|
||||
for algo in self.algoDict.values():
|
||||
for algo in list(self.algoDict.values()):
|
||||
setting[algo.spreadName] = algo.getAlgoParams()
|
||||
|
||||
f = shelve.open(self.algoFilePath)
|
||||
@ -478,7 +478,7 @@ class StAlgoEngine(object):
|
||||
if not setting:
|
||||
return
|
||||
|
||||
for algo in self.algoDict.values():
|
||||
for algo in list(self.algoDict.values()):
|
||||
if algo.spreadName in setting:
|
||||
d = setting[algo.spreadName]
|
||||
algo.setAlgoParams(d)
|
||||
@ -486,7 +486,7 @@ class StAlgoEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def stopAll(self):
|
||||
"""停止全部算法"""
|
||||
for algo in self.algoDict.values():
|
||||
for algo in list(self.algoDict.values()):
|
||||
algo.stop()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -506,7 +506,7 @@ class StAlgoEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def getAllAlgoParams(self):
|
||||
"""获取所有算法的参数"""
|
||||
return [algo.getAlgoParams() for algo in self.algoDict.values()]
|
||||
return [algo.getAlgoParams() for algo in list(self.algoDict.values())]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def setAlgoBuyPrice(self, spreadName, buyPrice):
|
||||
|
@ -429,7 +429,7 @@ class StAlgoManager(QtWidgets.QTableWidget):
|
||||
#----------------------------------------------------------------------
|
||||
def stopAll(self):
|
||||
"""停止所有算法"""
|
||||
for button in self.buttonActiveDict.values():
|
||||
for button in list(self.buttonActiveDict.values()):
|
||||
button.stop()
|
||||
|
||||
|
||||
|
@ -383,10 +383,10 @@ class CtpMdApi(MdApi):
|
||||
def onRtnDepthMarketData(self, data):
|
||||
"""行情推送"""
|
||||
# 忽略成交量为0的无效单合约tick数据
|
||||
if not data['Volume'] and '&' not in data['InstrumentID']:
|
||||
self.writeLog(u'忽略成交量为0的无效单合约tick数据:')
|
||||
self.writeLog(data)
|
||||
return
|
||||
#if not data['Volume'] and '&' not in data['InstrumentID']:
|
||||
# self.writeLog(u'忽略成交量为0的无效单合约tick数据:')
|
||||
# self.writeLog(data)
|
||||
# return
|
||||
|
||||
if not self.connectionStatus:
|
||||
self.connectionStatus = True
|
||||
@ -407,11 +407,19 @@ class CtpMdApi(MdApi):
|
||||
#tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec']/100)])
|
||||
# =》 Python 3
|
||||
tick.time = '.'.join([data['UpdateTime'], str(data['UpdateMillisec'])])
|
||||
tick.date = data['TradingDay']
|
||||
# 上期所和郑商所可以直接使用,大商所需要转换
|
||||
tick.date = data['ActionDay']
|
||||
# 大商所日期转换
|
||||
if tick.exchange is EXCHANGE_DCE:
|
||||
tick.date = datetime.now().strftime('%Y%m%d')
|
||||
|
||||
#tick.date = data['TradingDay']
|
||||
|
||||
# add by Incense Lee
|
||||
tick.tradingDay = data['TradingDay']
|
||||
|
||||
if len(tick.tradingDay) == 8:
|
||||
tradingDay = tick.tradingDay
|
||||
tick.tradingDay = "{}-{}-{}".format(tradingDay[:4], tradingDay[4:6], tradingDay[6:])
|
||||
# 先根据交易日期,生成时间
|
||||
tick.datetime = datetime.strptime(tick.date + ' ' + tick.time, '%Y%m%d %H:%M:%S.%f')
|
||||
# 修正时间
|
||||
@ -429,6 +437,8 @@ class CtpMdApi(MdApi):
|
||||
tick.datetime = tick.datetime + timedelta(days=2)
|
||||
tick.date = tick.datetime.strftime('%Y-%m-%d')
|
||||
|
||||
tick.date = tick.datetime.strftime('%Y-%m-%d')
|
||||
|
||||
tick.openPrice = data['OpenPrice']
|
||||
tick.highPrice = data['HighestPrice']
|
||||
tick.lowPrice = data['LowestPrice']
|
||||
@ -1437,7 +1447,7 @@ class CtpTdApi(TdApi):
|
||||
""""""
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def connect(self, userID, password, brokerID, address, authCode, userProductInfo):
|
||||
"""初始化连接"""
|
||||
self.userID = userID # 账号
|
||||
@ -1472,7 +1482,7 @@ class CtpTdApi(TdApi):
|
||||
elif not self.loginStatus:
|
||||
self.login()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def login(self):
|
||||
"""连接服务器"""
|
||||
# 如果填入了用户名密码等,则登录
|
||||
@ -1484,7 +1494,7 @@ class CtpTdApi(TdApi):
|
||||
self.reqID += 1
|
||||
self.reqUserLogin(req, self.reqID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def authenticate(self):
|
||||
"""申请验证"""
|
||||
if self.userID and self.brokerID and self.authCode and self.userProductInfo:
|
||||
@ -1496,13 +1506,13 @@ class CtpTdApi(TdApi):
|
||||
self.reqID +=1
|
||||
self.reqAuthenticate(req, self.reqID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def qryAccount(self):
|
||||
"""查询账户"""
|
||||
self.reqID += 1
|
||||
self.reqQryTradingAccount({}, self.reqID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def qryPosition(self):
|
||||
"""查询持仓"""
|
||||
self.reqID += 1
|
||||
@ -1511,7 +1521,7 @@ class CtpTdApi(TdApi):
|
||||
req['InvestorID'] = self.userID
|
||||
self.reqQryInvestorPosition(req, self.reqID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def sendOrder(self, orderReq):
|
||||
"""发单"""
|
||||
self.reqID += 1
|
||||
@ -1562,7 +1572,7 @@ class CtpTdApi(TdApi):
|
||||
vtOrderID = '.'.join([self.gatewayName, str(self.orderRef)])
|
||||
return vtOrderID
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def cancelOrder(self, cancelOrderReq):
|
||||
"""撤单"""
|
||||
self.reqID += 1
|
||||
@ -1581,12 +1591,12 @@ class CtpTdApi(TdApi):
|
||||
|
||||
self.reqOrderAction(req, self.reqID)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def close(self):
|
||||
"""关闭"""
|
||||
self.exit()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# ----------------------------------------------------------------------
|
||||
def writeLog(self, content):
|
||||
"""发出日志"""
|
||||
log = VtLogData()
|
||||
|
@ -72,14 +72,21 @@ EXCHANGE_IDEALPRO = 'IDEALPRO' # IB外汇ECN
|
||||
EXCHANGE_CME = 'CME' # CME交易所
|
||||
EXCHANGE_ICE = 'ICE' # ICE交易所
|
||||
|
||||
|
||||
EXCHANGE_OANDA = 'OANDA' # OANDA外汇做市商
|
||||
|
||||
|
||||
EXCHANGE_OKCOIN = 'OKCOIN' # OKCOIN比特币交易所
|
||||
EXCHANGE_HUOBI = 'HUOBI' # 火币比特币交易所
|
||||
EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所
|
||||
EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所
|
||||
EXCHANGE_BINANCE = 'BINANCE' # 币安比特币交易所
|
||||
EXCHANGE_GATEIO = 'GATEIO' # gate.io比特币交易所
|
||||
EXCHANGE_FCOIN = 'FCOIN' # fcoin.com 比特币交易所
|
||||
EXCHANGE_BITFINEX = "BITFINEX" # Bitfinex比特币交易所
|
||||
EXCHANGE_BITMEX = 'BITMEX' # BitMEX比特币交易所
|
||||
EXCHANGE_FCOIN = 'FCOIN' # FCoin比特币交易所
|
||||
EXCHANGE_BIGONE = 'BIGONE' # BigOne比特币交易所
|
||||
|
||||
# 货币类型
|
||||
CURRENCY_USD = 'USD' # 美元
|
||||
CURRENCY_CNY = 'CNY' # 人民币
|
||||
|
@ -80,7 +80,11 @@ EXCHANGE_LHANG = 'LHANG' # 链行比特币交易所
|
||||
EXCHANGE_OKEX = 'OKEX' # OKEX比特币交易所
|
||||
EXCHANGE_BINANCE = 'BINANCE' # 币安比特币交易所
|
||||
EXCHANGE_GATEIO = 'GATEIO' # gate.io比特币交易所
|
||||
EXCHANGE_FCOIN = 'FCOIN' # fcoin.com 比特币交易所
|
||||
EXCHANGE_BITFINEX = "BITFINEX" # Bitfinex比特币交易所
|
||||
EXCHANGE_BITMEX = 'BITMEX' # BitMEX比特币交易所
|
||||
EXCHANGE_FCOIN = 'FCOIN' # FCoin比特币交易所
|
||||
EXCHANGE_BIGONE = 'BIGONE' # BigOne比特币交易所
|
||||
|
||||
# 货币类型
|
||||
CURRENCY_USD = 'USD' # 美元
|
||||
CURRENCY_CNY = 'CNY' # 人民币
|
||||
|
@ -26,7 +26,7 @@ class GridKline(QtWidgets.QWidget):
|
||||
self.parent = parent
|
||||
super(GridKline, self).__init__(parent)
|
||||
|
||||
self.periods = ['m30', 'h1', 'h2', 'd']
|
||||
self.periods = ['m30', 'h1', 'h2','d']
|
||||
self.kline_dict = {}
|
||||
|
||||
self.initUI()
|
||||
@ -71,19 +71,23 @@ class GridKline(QtWidgets.QWidget):
|
||||
df = df.set_index(pd.DatetimeIndex(df['datetime']))
|
||||
canvas.loadData(df, main_indicators=['ma5', 'ma10', 'ma18'], sub_indicators=['sk', 'sd'])
|
||||
|
||||
# 载入 回测引擎生成的成交记录
|
||||
trade_list_file = 'TradeList.csv'
|
||||
if os.path.exists(trade_list_file):
|
||||
df_trade = pd.read_csv(trade_list_file)
|
||||
self.kline_dict['h1'].add_signals(df_trade)
|
||||
|
||||
# 载入策略生成的交易事务过程
|
||||
tns_file = 'tns.csv'
|
||||
if os.path.exists(tns_file):
|
||||
df_tns = pd.read_csv(tns_file)
|
||||
self.kline_dict['h2'].add_trans_df(df_tns)
|
||||
self.kline_dict['d'].add_trans_df(df_tns)
|
||||
|
||||
markup_file = 'dist.csv'
|
||||
if os.path.exists(markup_file):
|
||||
df_markup = pd.read_csv(markup_file)
|
||||
df_markup = df_markup[['datetime', 'price', 'operation']]
|
||||
df_markup.rename(columns={'operation': 'markup'}, inplace=True)
|
||||
self.kline_dict['m30'].add_markups(df_markup=df_markup, include_list=['balance'], exclude_list=['buy', 'short', 'sell', 'cover'])
|
||||
|
||||
except Exception as ex:
|
||||
traceback.print_exc()
|
||||
|
@ -6,7 +6,7 @@
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
import smtplib
|
||||
from threading import *
|
||||
from threading import Lock,Thread
|
||||
import time
|
||||
|
||||
# 创建一个带附件的实例
|
||||
@ -15,6 +15,23 @@ global maillock
|
||||
maillock = Lock()
|
||||
|
||||
|
||||
#用于发送邮件的邮箱列表
|
||||
senders_list = [('xxx010@163.com','xxxx'),
|
||||
('xxx013@163.com','xxxx'),
|
||||
('xxx014@163.com','xxxx'),
|
||||
('xxx015@163.com','xxxx'),
|
||||
('xxx016@163.com','xxxx'),
|
||||
('xxx017@163.com','xxxx'),
|
||||
('xxx018@163.com','xxxx'),
|
||||
('xxx019@163.com','xxxx'),
|
||||
('xxx020@163.com','xxxx'),
|
||||
('xxx021@163.com','xxxx'),
|
||||
('xxx022@163.com','xxxx'),
|
||||
('xxx023@163.com','xxxx'),
|
||||
('xxx024@163.com','xxxx'),
|
||||
('xxx025@163.com','xxxx'),
|
||||
('xxx026@163.com','xxxx'),
|
||||
('xxx027@163.com','xxxx')]
|
||||
class mail_thread(Thread):
|
||||
def __init__(self, to_list, subject, msgcontent, attachlist):
|
||||
super(mail_thread, self).__init__(name="mail_thread")
|
||||
@ -36,6 +53,16 @@ class mail_thread(Thread):
|
||||
self.lock.acquire()
|
||||
print("lock acquire %s" % time.ctime())
|
||||
|
||||
random_limit = len(senders_list) - 1
|
||||
if random_limit != 0:
|
||||
index = random.randint(0, random_limit)
|
||||
self.mailfrom, self.mailpwd = senders_list[index]
|
||||
|
||||
if len(self.mailfrom)==0 or len(self.mailpwd) == 0:
|
||||
print("sendmail user/pwd error!")
|
||||
self.lock.release()
|
||||
return
|
||||
|
||||
msg = MIMEMultipart()
|
||||
# 文本肉容
|
||||
content = MIMEText(self.msgcontent, _subtype='plain', _charset='gb2312')
|
||||
|
@ -7,7 +7,7 @@ from collections import OrderedDict
|
||||
import os,sys
|
||||
import copy
|
||||
|
||||
from pymongo import MongoClient
|
||||
from pymongo import MongoClient, ASCENDING
|
||||
from pymongo.errors import ConnectionFailure,AutoReconnect
|
||||
#import vnpy.trader.mongo_proxy
|
||||
|
||||
@ -26,7 +26,11 @@ import psutil
|
||||
try:
|
||||
from .util_mail import *
|
||||
except:
|
||||
print('import util_mail fail')
|
||||
print('import util_mail fail',file=sys.stderr)
|
||||
try:
|
||||
from .util_wechat import *
|
||||
except:
|
||||
print('import util_wechat fail',file=sys.stderr)
|
||||
|
||||
LOG_DB_NAME = 'vt_logger'
|
||||
|
||||
@ -147,16 +151,16 @@ class MainEngine(object):
|
||||
|
||||
def checkGatewayStatus(self,gatewayName):
|
||||
"""check gateway connect status"""
|
||||
# 借用检查网关状态来持久化合约数据
|
||||
self.save_contract_counter += 1
|
||||
if self.save_contract_counter > 60 and self.dataEngine is not None:
|
||||
self.writeLog(u'保存持久化合约数据')
|
||||
self.dataEngine.saveContracts()
|
||||
self.save_contract_counter = 0
|
||||
|
||||
if gatewayName in self.gatewayDict:
|
||||
gateway = self.gatewayDict[gatewayName]
|
||||
|
||||
# 借用检查网关状态来持久化合约数据
|
||||
self.save_contract_counter += 1
|
||||
if self.save_contract_counter > 60 and self.dataEngine is not None:
|
||||
|
||||
self.dataEngine.saveContracts()
|
||||
self.save_contract_counter = 0
|
||||
|
||||
return gateway.checkStatus()
|
||||
else:
|
||||
self.writeLog(text.GATEWAY_NOT_EXIST.format(gateway=gatewayName))
|
||||
@ -372,11 +376,22 @@ class MainEngine(object):
|
||||
# 写入本地log日志
|
||||
if self.logger is not None:
|
||||
self.logger.error(content)
|
||||
print('{}'.format(datetime.now()),file=sys.stderr)
|
||||
print(content, file=sys.stderr)
|
||||
else:
|
||||
print(content, file=sys.stderr)
|
||||
self.createLogger()
|
||||
|
||||
# 发出邮件/微信
|
||||
#try:
|
||||
# if len(self.gatewayDetailList) > 0:
|
||||
# target = self.gatewayDetailList[0]['gatewayName']
|
||||
# else:
|
||||
# target = WECHAT_GROUP["DEBUG_01"]
|
||||
# sendWeChatMsg(content, target=target, level=WECHAT_LEVEL_ERROR)
|
||||
#except Exception as ex:
|
||||
# print(u'send wechat exception:{}'.format(str(ex)),file=sys.stderr)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def writeWarning(self, content):
|
||||
"""快速发出告警日志事件"""
|
||||
@ -399,6 +414,16 @@ class MainEngine(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
# 发出微信
|
||||
#try:
|
||||
# if len(self.gatewayDetailList) > 0:
|
||||
# target = self.gatewayDetailList[0]['gatewayName']
|
||||
# else:
|
||||
# target = WECHAT_GROUP["DEBUG_01"]
|
||||
# sendWeChatMsg(content, target=target, level=WECHAT_LEVEL_WARNING)
|
||||
#except Exception as ex:
|
||||
# print(u'send wechat exception:{}'.format(str(ex)), file=sys.stderr)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def writeNotification(self, content):
|
||||
"""快速发出通知日志事件"""
|
||||
@ -414,6 +439,16 @@ class MainEngine(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
# 发出微信
|
||||
# try:
|
||||
# if len(self.gatewayDetailList) > 0:
|
||||
# target = self.gatewayDetailList[0]['gatewayName']
|
||||
# else:
|
||||
# target = WECHAT_GROUP["DEBUG_01"]
|
||||
# sendWeChatMsg(content, target=target, level=WECHAT_LEVEL_INFO)
|
||||
# except Exception as ex:
|
||||
# print(u'send wechat exception:{}'.format(str(ex)), file=sys.stderr)
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def writeCritical(self, content):
|
||||
"""快速发出严重错误日志事件"""
|
||||
@ -427,6 +462,7 @@ class MainEngine(object):
|
||||
# 写入本地log日志
|
||||
if self.logger:
|
||||
self.logger.critical(content)
|
||||
print('{}'.format(datetime.now()), file=sys.stderr)
|
||||
print(content, file=sys.stderr)
|
||||
else:
|
||||
print(content, file=sys.stderr)
|
||||
@ -438,6 +474,16 @@ class MainEngine(object):
|
||||
except:
|
||||
pass
|
||||
|
||||
## 发出微信
|
||||
#try:
|
||||
# # if len(self.gatewayDetailList) > 0:
|
||||
# target = self.gatewayDetailList[0]['gatewayName']
|
||||
# else:
|
||||
# target = WECHAT_GROUP["DEBUG_01"]
|
||||
# sendWeChatMsg(content, target=target, level=WECHAT_LEVEL_FATAL)
|
||||
#except:
|
||||
# pass
|
||||
#
|
||||
# ----------------------------------------------------------------------
|
||||
def dbConnect(self):
|
||||
"""连接MongoDB数据库"""
|
||||
@ -527,13 +573,18 @@ class MainEngine(object):
|
||||
self.writeError(u'dbInsertMany exception:{}'.format(str(ex)))
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
def dbQuery(self, dbName, collectionName, d):
|
||||
def dbQuery(self, dbName, collectionName, d, sortKey='', sortDirection=ASCENDING):
|
||||
"""从MongoDB中读取数据,d是查询要求,返回的是数据库查询的指针"""
|
||||
try:
|
||||
if self.dbClient:
|
||||
db = self.dbClient[dbName]
|
||||
collection = db[collectionName]
|
||||
cursor = collection.find(d)
|
||||
|
||||
if sortKey:
|
||||
cursor = collection.find(d).sort(sortKey, sortDirection) # 对查询出来的数据进行排序
|
||||
else:
|
||||
cursor = collection.find(d)
|
||||
|
||||
if cursor:
|
||||
return list(cursor)
|
||||
else:
|
||||
|
@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
import time,os
|
||||
import time,os,sys
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.trader.vtEvent import *
|
||||
@ -98,10 +98,11 @@ class VtGateway(object):
|
||||
event1.dict_['data'] = error
|
||||
self.eventEngine.put(event1)
|
||||
|
||||
logMsg = u'{0}:[{1}]:{2}'.format(error.gatewayName, error.errorID,error.errorMsg )
|
||||
logMsg = u'{} {}:[{}]:{}'.format(datetime.now(), error.gatewayName, error.errorID,error.errorMsg )
|
||||
# 写入本地log日志
|
||||
if self.logger:
|
||||
self.logger.info(logMsg)
|
||||
self.logger.error(logMsg)
|
||||
print(logMsg,file=sys.stderr)
|
||||
else:
|
||||
self.createLogger()
|
||||
|
||||
@ -205,12 +206,9 @@ class VtGateway(object):
|
||||
error.errorMsg = content
|
||||
self.onError(error)
|
||||
|
||||
# 输出到错误管道
|
||||
print(u'{}:{} {}'.format(datetime.now(),self.gatewayName,content),file=sys.stderr)
|
||||
|
||||
if self.logger:
|
||||
self.logger.error(content)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user