更新
This commit is contained in:
parent
23789fda72
commit
7cceddb227
@ -1182,14 +1182,18 @@ class TradingWidget(QtWidgets.QFrame):
|
||||
pos = cell.data
|
||||
symbol = pos.symbol
|
||||
|
||||
# 拆分 合约.交易所接口
|
||||
symbol_split_list = symbol.split('.')
|
||||
if len(symbol_split_list)==2:
|
||||
exchange_name = symbol_split_list[-1]
|
||||
if exchange_name in [EXCHANGE_OKEX,EXCHANGE_BINANCE,EXCHANGE_HUOBI,EXCHANGE_GATEIO]:
|
||||
symbol = symbol_split_list[0]
|
||||
|
||||
if len(symbol_split_list)==2:
|
||||
# 交易所
|
||||
exchange_name = symbol_split_list[-1]
|
||||
|
||||
# 数字货币类交易所
|
||||
if exchange_name in [EXCHANGE_OKEX,EXCHANGE_BINANCE,EXCHANGE_HUOBI,EXCHANGE_GATEIO]:
|
||||
symbol_pair_list = symbol.split('_')
|
||||
if len(symbol_pair_list) ==1:
|
||||
# 获取合约
|
||||
if symbol.lower() == 'usdt':
|
||||
return
|
||||
symbol = symbol_pair_list[0] + '_' + 'usdt'+'.'+symbol_split_list[-1]
|
||||
|
@ -298,6 +298,7 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||
return
|
||||
|
||||
def connect():
|
||||
r = False
|
||||
try:
|
||||
r = self.mainEngine.connect(gatewayName)
|
||||
except:
|
||||
|
@ -1,21 +1,19 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
'''
|
||||
多RPC监控界面组件
|
||||
Author: IncenseLee
|
||||
|
||||
设计思路:
|
||||
1、单一RPC监控组件,包括:
|
||||
1)连接
|
||||
2)服务端状态监控(是否运行,gw名称,连接状态;操作:停止服务端,停止gw连接,启动gw连接)
|
||||
3)服务端策略状态监控(策略名称,ValueMonitor,信号。操作:启动策略,停止策略,初始化策略,强制初始化策略,特殊操作。。)
|
||||
4)服务器端Warning\Error\Nofification\Critical Log
|
||||
2、多RPC监控容器,包括:
|
||||
1)从本地VT_Setting读取服务端连接信息。进行初始化和连接。
|
||||
2)订阅相应Event
|
||||
|
||||
'''
|
||||
|
||||
#多RPC监控界面组件
|
||||
#Author: IncenseLee
|
||||
#
|
||||
#设计思路:
|
||||
#1、单一RPC监控组件,包括:
|
||||
# 1)连接
|
||||
# 2)服务端状态监控(是否运行,gw名称,连接状态;操作:停止服务端,停止gw连接,启动gw连接)
|
||||
# 3)服务端策略状态监控(策略名称,ValueMonitor,信号。操作:启动策略,停止策略,初始化策略,强制初始化策略,特殊操作。。)
|
||||
# 4)服务器端Warning\Error\Nofification\Critical Log
|
||||
#2、多RPC监控容器,包括:
|
||||
# 1)从本地VT_Setting读取服务端连接信息。进行初始化和连接。
|
||||
# 2)订阅相应Event
|
||||
#
|
||||
|
||||
import os
|
||||
import sys
|
||||
@ -90,12 +88,15 @@ class StrategyMonitorWidget(QtWidgets.QGroupBox):
|
||||
btnStopStrategy.clicked.connect(self.stop_strategy)
|
||||
btnForceInitStrategy = QtWidgets.QPushButton(u'ForceInit')
|
||||
btnForceInitStrategy.clicked.connect(self.force_init_strategy)
|
||||
btnDispatchOutStrategy = QtWidgets.QPushButton(u'Dispatch Out')
|
||||
btnDispatchOutStrategy.clicked.connect(self.remove_strategy)
|
||||
|
||||
hbox1 = QtWidgets.QHBoxLayout()
|
||||
hbox1.addWidget(btnInitStrategy)
|
||||
hbox1.addWidget(btnStartStrategy)
|
||||
hbox1.addWidget(btnStopStrategy)
|
||||
hbox1.addWidget(btnForceInitStrategy)
|
||||
#hbox1.addWidget(btnDispatchOutStrategy)
|
||||
hbox1.addStretch()
|
||||
|
||||
# 策略的运行数据表
|
||||
@ -128,6 +129,14 @@ class StrategyMonitorWidget(QtWidgets.QGroupBox):
|
||||
if self.mainEngine:
|
||||
self.mainEngine.initStrategy(self.name, force=True)
|
||||
|
||||
def remove_strategy(self):
|
||||
if self.mainEngine and hasattr(self.mainEngine,'removeStrategy'):
|
||||
print('call removeStrategy({})'.format(self.name))
|
||||
self.mainEngine.removeStrategy(self.name)
|
||||
else:
|
||||
print('cant not call removeStrategy',file=sys.stderr)
|
||||
|
||||
|
||||
class CtaEngineMonitorWidget(QtWidgets.QWidget):
|
||||
"""RPC 服务端CTA引擎监控组件
|
||||
{策略名称,ValueMonitor;操作:启动策略,停止策略,初始化策略,强制初始化策略,特殊操作。。)}
|
||||
@ -146,23 +155,27 @@ class CtaEngineMonitorWidget(QtWidgets.QWidget):
|
||||
|
||||
self.initUi()
|
||||
self.initVarMonitors = False
|
||||
self.monitor_vbox = None
|
||||
|
||||
def setMainEngine(self,mainEngine):
|
||||
self.mainEngine = mainEngine
|
||||
|
||||
def initUi(self):
|
||||
btnLoadStrategies = QtWidgets.QPushButton(u'Load All Strategies')
|
||||
|
||||
btnStartStrategies = QtWidgets.QPushButton(u'Start All Strategies')
|
||||
btnStopStrategies = QtWidgets.QPushButton(u'Stop All Strategies')
|
||||
btnAddStrategy = QtWidgets.QPushButton(u'Add Strategy')
|
||||
|
||||
|
||||
btnLoadStrategies.clicked.connect(self.load_all_strategies)
|
||||
btnStartStrategies.clicked.connect(self.start_all_strategies)
|
||||
btnStopStrategies.clicked.connect(self.stop_all_strategies)
|
||||
btnAddStrategy.clicked.connect(self.add_new_strategy)
|
||||
|
||||
hbox1 = QtWidgets.QHBoxLayout()
|
||||
hbox1.addWidget(btnLoadStrategies)
|
||||
|
||||
hbox1.addWidget(btnStartStrategies)
|
||||
hbox1.addWidget(btnStopStrategies)
|
||||
#hbox1.addWidget(btnAddStrategy)
|
||||
hbox1.addStretch()
|
||||
|
||||
self.vbox = QtWidgets.QVBoxLayout()
|
||||
@ -171,15 +184,65 @@ class CtaEngineMonitorWidget(QtWidgets.QWidget):
|
||||
|
||||
self.setLayout(self.vbox)
|
||||
|
||||
def load_all_strategies(self):
|
||||
if self.mainEngine:
|
||||
pass
|
||||
|
||||
def start_all_strategies(self):
|
||||
pass
|
||||
"""
|
||||
启动调度服务器内所有运行中的策略
|
||||
:return:
|
||||
"""
|
||||
if self.mainEngine and hasattr(self.mainEngine, 'startStrategy'):
|
||||
for strategy_name in self.strategy_monitors.keys():
|
||||
try:
|
||||
self.mainEngine.startStrategy(strategy_name)
|
||||
except Exception as ex:
|
||||
print(u'调用启动{}策略时发生异常:{},{}'.format(strategy_name, str(ex), traceback.format_exc()))
|
||||
continue
|
||||
|
||||
def stop_all_strategies(self):
|
||||
pass
|
||||
"""
|
||||
停止调度服务器内所有运行中的策略
|
||||
:return:
|
||||
"""
|
||||
if self.mainEngine and hasattr(self.mainEngine,'stopStrategy'):
|
||||
for strategy_name in self.strategy_monitors.keys():
|
||||
try:
|
||||
self.mainEngine.stopStrategy(strategy_name)
|
||||
except Exception as ex:
|
||||
print(u'调用停止{}策略时发生异常:{},{}'.format(strategy_name,str(ex), traceback.format_exc()))
|
||||
continue
|
||||
|
||||
def add_new_strategy(self):
|
||||
"""
|
||||
添加新的cta策略配置到运行中的调度服务器
|
||||
:return:
|
||||
"""
|
||||
value, ok = QtWidgets.QInputDialog.getMultiLineText(self, "输入CTA策略设置", "ditc结构", "{\n\n\n}")
|
||||
if not ok:
|
||||
return
|
||||
|
||||
if len(value) == 0:
|
||||
return
|
||||
|
||||
cta_setting = None
|
||||
try:
|
||||
cta_setting = json.loads(value)
|
||||
except Exception as ex:
|
||||
print(u'{}{}'.format(str(ex),traceback.format_exc()),file=sys.stderr)
|
||||
return
|
||||
|
||||
if not isinstance(cta_setting, dict):
|
||||
print(u'输入得不是dict结构',file=sys.stderr)
|
||||
return
|
||||
|
||||
if cta_setting.get('name',None) == None or cta_setting.get('className',None) == None:
|
||||
print(u'输入设置里面缺少name/className', file=sys.stderr)
|
||||
return
|
||||
|
||||
if self.mainEngine and hasattr(self.mainEngine, 'addStrategy'):
|
||||
print('call addStrategy({})'.format(cta_setting))
|
||||
self.mainEngine.addStrategy(cta_setting)
|
||||
else:
|
||||
print('cant not call addStrategy:{}'.format(cta_setting), file=sys.stderr)
|
||||
|
||||
def updateStatus(self, status_dict):
|
||||
"""更新状态数据"""
|
||||
@ -188,16 +251,16 @@ class CtaEngineMonitorWidget(QtWidgets.QWidget):
|
||||
|
||||
if not self.initVarMonitors:
|
||||
w = QtWidgets.QWidget()
|
||||
vbox = QtWidgets.QVBoxLayout()
|
||||
for k, v in status_dict.items():
|
||||
self.monitor_vbox = QtWidgets.QVBoxLayout()
|
||||
|
||||
strategy_names = status_dict.keys()
|
||||
sorted_strategy_names = sorted(strategy_names)
|
||||
for k in sorted_strategy_names:
|
||||
monitor = StrategyMonitorWidget(name=k, mainEngine=self.mainEngine, parent=self)
|
||||
#height = 65
|
||||
#monitor.setFixedHeight(height)
|
||||
|
||||
self.strategy_monitors[k] = monitor
|
||||
vbox.addWidget(monitor)
|
||||
self.monitor_vbox.addWidget(monitor)
|
||||
|
||||
w.setLayout(vbox)
|
||||
w.setLayout(self.monitor_vbox)
|
||||
self.scrollArea.setWidget(w)
|
||||
self.initVarMonitors = True
|
||||
|
||||
@ -205,6 +268,13 @@ class CtaEngineMonitorWidget(QtWidgets.QWidget):
|
||||
if k in self.strategy_monitors:
|
||||
monitor = self.strategy_monitors[k]
|
||||
monitor.updateStatus(v)
|
||||
else:
|
||||
monitor = StrategyMonitorWidget(name=k, mainEngine=self.mainEngine, parent=self)
|
||||
self.strategy_monitors[k] = monitor
|
||||
if self.monitor_vbox is not None:
|
||||
self.monitor_vbox.addWidget(monitor)
|
||||
monitor.updateStatus(v)
|
||||
|
||||
|
||||
class ServerInfoWidget(QtWidgets.QWidget):
|
||||
"""服务器信息显示组件
|
||||
@ -250,12 +320,11 @@ class AccountMonitorWidget(QtWidgets.QWidget):
|
||||
|
||||
########################################################################
|
||||
class RpcServerMonitor(QtWidgets.QWidget):
|
||||
"""RPC服务端监控容器组件
|
||||
1)连接服务端,gw名称,
|
||||
2)连接状态;操作:停止服务端,停止gw连接,启动gw连接)
|
||||
3)CtaEngineMonitorWidget
|
||||
4)RpcEventLogMonitor Warning\Error\Nofification\Critical Log
|
||||
"""
|
||||
#RPC服务端监控容器组件
|
||||
#1)连接服务端,gw名称,
|
||||
#2)连接状态;操作:停止服务端,停止gw连接,启动gw连接)
|
||||
#3)CtaEngineMonitorWidget
|
||||
#4)RpcEventLogMonitor Warning\Error\Nofification\Critical Log
|
||||
|
||||
signal = QtCore.Signal(type(Event()))
|
||||
|
||||
@ -274,7 +343,7 @@ class RpcServerMonitor(QtWidgets.QWidget):
|
||||
self.rpc_client = None
|
||||
self.mainEngine = None
|
||||
|
||||
self.server_info_monitor= None
|
||||
self.server_info_monitor = None
|
||||
|
||||
self.initUi()
|
||||
# ----------------------------------------------------------------------
|
||||
@ -429,7 +498,6 @@ class RpcServerMonitor(QtWidgets.QWidget):
|
||||
self.updateCritical(event)
|
||||
return
|
||||
|
||||
|
||||
def updateStatus(self,event):
|
||||
"""更新Status"""
|
||||
status_dict = event.dict_['data']
|
||||
@ -553,16 +621,17 @@ class MultiRpcServerManager(QtWidgets.QMainWindow):
|
||||
except Exception as ex:
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.warning(self, 'Exception',u'Load vt_Setting.json Exception', QtWidgets.QMessageBox.Cancel,
|
||||
QtWidgets.QMessageBox.NoButton, QtGui.QMessageBox.NoButton)
|
||||
QtWidgets.QMessageBox.NoButton)
|
||||
|
||||
return
|
||||
|
||||
|
||||
def closeEvent(self, event):
|
||||
"""关闭窗口时的事件"""
|
||||
self.mdi.closeAllSubWindows()
|
||||
event.accept()
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
from vnpy.trader.uiQt import createQApp
|
||||
|
@ -1,6 +1,6 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
print('load vtEngine.py')
|
||||
print(u'启动load vtEngine.py')
|
||||
|
||||
import shelve
|
||||
from collections import OrderedDict
|
||||
|
@ -6,7 +6,7 @@ from datetime import datetime
|
||||
|
||||
from vnpy.trader.vtConstant import (EMPTY_STRING, EMPTY_UNICODE,
|
||||
EMPTY_FLOAT, EMPTY_INT)
|
||||
|
||||
from vnpy.trader.language import constant
|
||||
|
||||
########################################################################
|
||||
class VtBaseData(object):
|
||||
@ -77,6 +77,35 @@ class VtTickData(VtBaseData):
|
||||
self.askVolume4 = EMPTY_FLOAT
|
||||
self.askVolume5 = EMPTY_FLOAT
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromGateway(gateway, symbol, exchange,
|
||||
lastPrice, lastVolume,
|
||||
highPrice, lowPrice,
|
||||
openPrice=EMPTY_FLOAT,
|
||||
openInterest=EMPTY_INT,
|
||||
upperLimit=EMPTY_FLOAT,
|
||||
lowerLimit=EMPTY_FLOAT):
|
||||
tick = VtTickData()
|
||||
tick.gatewayName = gateway.gatewayName
|
||||
tick.symbol = symbol
|
||||
tick.exchange = exchange
|
||||
tick.vtSymbol = symbol + '.' + exchange
|
||||
|
||||
tick.lastPrice = lastPrice
|
||||
tick.lastVolume = lastVolume
|
||||
tick.openInterest = openInterest
|
||||
tick.datetime = datetime.now()
|
||||
tick.date = tick.datetime.strftime('%Y%m%d')
|
||||
tick.time = tick.datetime.strftime('%H:%M:%S')
|
||||
|
||||
tick.openPrice = openPrice
|
||||
tick.highPrice = highPrice
|
||||
tick.lowPrice = lowPrice
|
||||
tick.upperLimit = upperLimit
|
||||
tick.lowerLimit = lowerLimit
|
||||
return tick
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtBarData(VtBaseData):
|
||||
@ -130,6 +159,48 @@ class VtTradeData(VtBaseData):
|
||||
self.volume = EMPTY_FLOAT # 成交数量
|
||||
self.tradeTime = EMPTY_STRING # 成交时间
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromGateway(gateway, symbol, exchange, tradeID, orderID, direction, tradePrice, tradeVolume):
|
||||
trade = VtTradeData()
|
||||
trade.gatewayName = gateway.gatewayName
|
||||
trade.symbol = symbol
|
||||
trade.exchange = exchange
|
||||
trade.vtSymbol = symbol + '.' + exchange
|
||||
|
||||
trade.orderID = orderID
|
||||
trade.vtOrderID = trade.gatewayName + '.' + trade.tradeID
|
||||
|
||||
trade.tradeID = tradeID
|
||||
trade.vtTradeID = trade.gatewayName + '.' + tradeID
|
||||
|
||||
trade.direction = direction
|
||||
trade.price = tradePrice
|
||||
trade.volume = tradeVolume
|
||||
trade.tradeTime = datetime.now().strftime('%H:%M:%S')
|
||||
return trade
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromOrderData(order,
|
||||
tradeID,
|
||||
tradePrice,
|
||||
tradeVolume): # type: (VtOrderData, str, float, float)->VtTradeData
|
||||
trade = VtTradeData()
|
||||
trade.gatewayName = order.gatewayName
|
||||
trade.symbol = order.symbol
|
||||
trade.vtSymbol = order.vtSymbol
|
||||
|
||||
trade.orderID = order.orderID
|
||||
trade.vtOrderID = order.vtOrderID
|
||||
trade.tradeID = tradeID
|
||||
trade.vtTradeID = trade.gatewayName + '.' + tradeID
|
||||
trade.direction = order.direction
|
||||
trade.price = tradePrice
|
||||
trade.volume = tradeVolume
|
||||
trade.tradeTime = datetime.now().strftime('%H:%M:%S')
|
||||
return trade
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtOrderData(VtBaseData):
|
||||
@ -164,6 +235,39 @@ class VtOrderData(VtBaseData):
|
||||
self.frontID = EMPTY_INT # 前置机编号
|
||||
self.sessionID = EMPTY_INT # 连接编号
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromGateway(gateway, # type: VtGateway
|
||||
orderId, # type: str
|
||||
symbol, # type: str
|
||||
exchange, # type: str
|
||||
price, # type: float
|
||||
volume, # type: int
|
||||
direction, # type: str
|
||||
offset=EMPTY_UNICODE, # type: str
|
||||
tradedVolume=EMPTY_INT, # type: int
|
||||
status=constant.STATUS_UNKNOWN, # type: str
|
||||
orderTime=EMPTY_UNICODE, # type: str
|
||||
cancelTime=EMPTY_UNICODE, # type: str
|
||||
): # type: (...)->VtOrderData
|
||||
vtOrder = VtOrderData()
|
||||
vtOrder.gatewayName = gateway.gatewayName
|
||||
vtOrder.symbol = symbol
|
||||
vtOrder.exchange = exchange
|
||||
vtOrder.vtSymbol = symbol + '.' + exchange
|
||||
vtOrder.orderID = orderId
|
||||
vtOrder.vtOrderID = gateway.gatewayName + '.' + orderId
|
||||
|
||||
vtOrder.direction = direction
|
||||
vtOrder.offset = offset
|
||||
vtOrder.price = price
|
||||
vtOrder.totalVolume = volume
|
||||
vtOrder.tradedVolume = tradedVolume
|
||||
vtOrder.status = status
|
||||
vtOrder.orderTime = orderTime
|
||||
vtOrder.cancelTime = cancelTime
|
||||
return vtOrder
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtPositionData(VtBaseData):
|
||||
@ -188,6 +292,33 @@ class VtPositionData(VtBaseData):
|
||||
self.ydPosition = EMPTY_INT # 昨持仓
|
||||
self.positionProfit = EMPTY_FLOAT # 持仓盈亏
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromGateway(gateway, # type: VtGateway
|
||||
exchange, # type: str
|
||||
symbol, # type: str
|
||||
direction, # type: str
|
||||
position, # type: int
|
||||
frozen=EMPTY_INT, # type: int
|
||||
price=EMPTY_FLOAT, # type: float
|
||||
yestordayPosition=EMPTY_INT, # type: int
|
||||
profit=EMPTY_FLOAT # type: float
|
||||
): # type: (...)->VtPositionData
|
||||
vtPosition = VtPositionData()
|
||||
vtPosition.gatewayName = gateway.gatewayName
|
||||
vtPosition.symbol = symbol
|
||||
vtPosition.exchange = exchange
|
||||
vtPosition.vtSymbol = symbol + '.' + exchange
|
||||
|
||||
vtPosition.direction = direction
|
||||
vtPosition.position = position
|
||||
vtPosition.frozen = frozen
|
||||
vtPosition.price = price
|
||||
vtPosition.vtPositionName = vtPosition.vtSymbol + '.' + direction
|
||||
vtPosition.ydPosition = yestordayPosition
|
||||
vtPosition.positionProfit = profit
|
||||
return vtPosition
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtAccountData(VtBaseData):
|
||||
@ -281,9 +412,56 @@ class VtContractData(VtBaseData):
|
||||
self.strikePrice = EMPTY_FLOAT # 期权行权价
|
||||
self.underlyingSymbol = EMPTY_STRING # 标的物合约代码
|
||||
self.optionType = EMPTY_UNICODE # 期权类型
|
||||
self.expiryDate = EMPTY_STRING # 到期日
|
||||
|
||||
# 数字货币有关
|
||||
self.volumeTick = EMPTY_FLOAT #合约最小交易量
|
||||
# ----------------------------------------------------------------------
|
||||
@staticmethod
|
||||
def createFromGateway(gateway,
|
||||
exchange,
|
||||
symbol,
|
||||
productClass,
|
||||
size,
|
||||
priceTick,
|
||||
name=None,
|
||||
strikePrice=EMPTY_FLOAT,
|
||||
underlyingSymbol=EMPTY_STRING,
|
||||
optionType=EMPTY_UNICODE,
|
||||
expiryDate=EMPTY_STRING
|
||||
):
|
||||
d = VtContractData()
|
||||
d.gatewayName = gateway.gatewayName
|
||||
d.symbol = symbol
|
||||
d.exchange = exchange
|
||||
d.vtSymbol = symbol + '.' + exchange
|
||||
d.productClass = productClass
|
||||
d.size = size
|
||||
d.priceTick = priceTick
|
||||
if name is None:
|
||||
d.name = d.symbol
|
||||
d.strikePrice = strikePrice
|
||||
d.underlyingSymbol = underlyingSymbol
|
||||
d.optionType = optionType
|
||||
d.expiryDate = expiryDate
|
||||
return d
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtHistoryData(object):
|
||||
"""K线时间序列数据"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.vtSymbol = EMPTY_STRING # vt系统代码
|
||||
self.symbol = EMPTY_STRING # 代码
|
||||
self.exchange = EMPTY_STRING # 交易所
|
||||
|
||||
self.interval = EMPTY_UNICODE # K线时间周期
|
||||
self.queryID = EMPTY_STRING # 查询号
|
||||
self.barList = [] # VtBarData列表
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtSubscribeReq(object):
|
||||
@ -346,3 +524,35 @@ class VtCancelOrderReq(object):
|
||||
self.frontID = EMPTY_STRING # 前置机号
|
||||
self.sessionID = EMPTY_STRING # 会话号
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtHistoryReq(object):
|
||||
"""查询历史数据时传入的对象类"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.symbol = EMPTY_STRING # 代码
|
||||
self.exchange = EMPTY_STRING # 交易所
|
||||
self.vtSymbol = EMPTY_STRING # VT合约代码
|
||||
|
||||
self.interval = EMPTY_UNICODE # K线周期
|
||||
self.start = None # 起始时间datetime对象
|
||||
self.end = None # 结束时间datetime对象
|
||||
|
||||
|
||||
########################################################################
|
||||
class VtSingleton(type):
|
||||
"""
|
||||
单例,应用方式:静态变量 __metaclass__ = Singleton
|
||||
"""
|
||||
|
||||
_instances = {}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __call__(cls, *args, **kwargs):
|
||||
"""调用"""
|
||||
if cls not in cls._instances:
|
||||
cls._instances[cls] = super(VtSingleton, cls).__call__(*args, **kwargs)
|
||||
|
||||
return cls._instances[cls]
|
||||
|
Loading…
Reference in New Issue
Block a user