初步完成价差交易界面
This commit is contained in:
parent
2578e1b419
commit
79a9ac2bfb
Binary file not shown.
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 65 KiB |
@ -12,9 +12,9 @@ from vnpy.trader.vtConstant import (EMPTY_INT, EMPTY_FLOAT,
|
|||||||
########################################################################
|
########################################################################
|
||||||
class StAlgoTemplate(object):
|
class StAlgoTemplate(object):
|
||||||
"""价差算法交易模板"""
|
"""价差算法交易模板"""
|
||||||
MODE_LONGSHORT = 1
|
MODE_LONGSHORT = u'双向'
|
||||||
MODE_LONGONLY = 2
|
MODE_LONGONLY = u'做多'
|
||||||
MODE_SHORTONLY = 3
|
MODE_SHORTONLY = u'做空'
|
||||||
|
|
||||||
SPREAD_LONG = 1
|
SPREAD_LONG = 1
|
||||||
SPREAD_SHORT = 2
|
SPREAD_SHORT = 2
|
||||||
@ -65,7 +65,7 @@ class StAlgoTemplate(object):
|
|||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def start(self, mode=MODE_LONGSHORT):
|
def start(self):
|
||||||
""""""
|
""""""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
@ -74,7 +74,79 @@ class StAlgoTemplate(object):
|
|||||||
""""""
|
""""""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setBuyPrice(self, buyPrice):
|
||||||
|
"""设置买开的价格"""
|
||||||
|
self.buyPrice = buyPrice
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setSellPrice(self, sellPrice):
|
||||||
|
"""设置卖平的价格"""
|
||||||
|
self.sellPrice = sellPrice
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setShortPrice(self, shortPrice):
|
||||||
|
"""设置卖开的价格"""
|
||||||
|
self.shortPrice = shortPrice
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setCoverPrice(self, coverPrice):
|
||||||
|
"""设置买平的价格"""
|
||||||
|
self.coverPrice = coverPrice
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setMode(self, mode):
|
||||||
|
"""设置算法交易方向"""
|
||||||
|
self.mode = mode
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setMaxOrderSize(self, maxOrderSize):
|
||||||
|
"""设置最大单笔委托数量"""
|
||||||
|
self.maxOrderSize = maxOrderSize
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setMaxPosSize(self, maxPosSize):
|
||||||
|
"""设置最大持仓数量"""
|
||||||
|
self.maxPosSize = maxPosSize
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putEvent(self):
|
||||||
|
"""发出算法更新事件"""
|
||||||
|
self.algoEngine.putAlgoEvent(self)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def writeLog(self, content):
|
||||||
|
"""输出算法日志"""
|
||||||
|
content = ':'.join([self.spreadName, content])
|
||||||
|
self.algoEngine.writeLog(content)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getAlgoParams(self):
|
||||||
|
"""获取算法参数"""
|
||||||
|
d = {
|
||||||
|
"spreadName": self.spreadName,
|
||||||
|
"algoName": self.algoName,
|
||||||
|
"buyPrice": self.buyPrice,
|
||||||
|
"sellPrice": self.sellPrice,
|
||||||
|
"shortPrice": self.shortPrice,
|
||||||
|
"coverPrice": self.coverPrice,
|
||||||
|
"maxOrderSize": self.maxOrderSize,
|
||||||
|
"maxPosSize": self.maxPosSize,
|
||||||
|
"mode": self.mode
|
||||||
|
}
|
||||||
|
return d
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoParams(self, d):
|
||||||
|
"""设置算法参数"""
|
||||||
|
self.buyPrice = d.get('buyPrice', EMPTY_FLOAT)
|
||||||
|
self.sellPrice = d.get('sellPrice', EMPTY_FLOAT)
|
||||||
|
self.shortPrice = d.get('shortPrice', EMPTY_FLOAT)
|
||||||
|
self.coverPrice = d.get('coverPrice', EMPTY_FLOAT)
|
||||||
|
self.maxOrderSize = d.get('maxOrderSize', EMPTY_INT)
|
||||||
|
self.maxPosSize = d.get('maxPosSize', EMPTY_INT)
|
||||||
|
self.mode = d.get('mode', self.MODE_LONGSHORT)
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class SniperAlgo(StAlgoTemplate):
|
class SniperAlgo(StAlgoTemplate):
|
||||||
@ -82,9 +154,9 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_CANCELLED, STATUS_REJECTED]
|
FINISHED_STATUS = [STATUS_ALLTRADED, STATUS_CANCELLED, STATUS_REJECTED]
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def __init__(self, algoEngine):
|
def __init__(self, algoEngine, spread):
|
||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
super(SniperAlgo, self).__init__(algoEngine)
|
super(SniperAlgo, self).__init__(algoEngine, spread)
|
||||||
|
|
||||||
self.algoName = u'Sniper'
|
self.algoName = u'Sniper'
|
||||||
self.quoteInterval = 2 # 主动腿报价撤单再发前等待的时间
|
self.quoteInterval = 2 # 主动腿报价撤单再发前等待的时间
|
||||||
@ -125,11 +197,13 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
spread.netPos < self.maxPosSize and
|
spread.netPos < self.maxPosSize and
|
||||||
spread.askPrice <= self.buyPrice):
|
spread.askPrice <= self.buyPrice):
|
||||||
self.quoteActiveLeg(self.SPREAD_LONG)
|
self.quoteActiveLeg(self.SPREAD_LONG)
|
||||||
|
self.writeLog(u'买入开仓')
|
||||||
|
|
||||||
# 卖出
|
# 卖出
|
||||||
elif (spread.netPos > 0 and
|
elif (spread.netPos > 0 and
|
||||||
spread.bidPrice >= self.sellPrice):
|
spread.bidPrice >= self.sellPrice):
|
||||||
self.quoteActiveLeg(self.SPREAD_SHORT)
|
self.quoteActiveLeg(self.SPREAD_SHORT)
|
||||||
|
self.writeLog(u'卖出平仓')
|
||||||
|
|
||||||
# 允许做空
|
# 允许做空
|
||||||
if self.mode == self.MODE_LONGSHORT or self.mode == self.MODE_SHORTONLY:
|
if self.mode == self.MODE_LONGSHORT or self.mode == self.MODE_SHORTONLY:
|
||||||
@ -138,11 +212,13 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
spread.netPos > -self.maxPosSize and
|
spread.netPos > -self.maxPosSize and
|
||||||
spread.bidPrice >= self.shortPrice):
|
spread.bidPrice >= self.shortPrice):
|
||||||
self.quoteActiveLeg(self.SPREAD_SHORT)
|
self.quoteActiveLeg(self.SPREAD_SHORT)
|
||||||
|
self.writeLog(u'卖出开仓')
|
||||||
|
|
||||||
# 平空
|
# 平空
|
||||||
elif (spread.netPos < 0 and
|
elif (spread.netPos < 0 and
|
||||||
spread.askPrice <= self.coverPrice):
|
spread.askPrice <= self.coverPrice):
|
||||||
self.quoteActiveLeg(self.SPREAD_LONG)
|
self.quoteActiveLeg(self.SPREAD_LONG)
|
||||||
|
self.writeLog(u'买入平仓')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateSpreadPos(self, spread):
|
def updateSpreadPos(self, spread):
|
||||||
@ -180,10 +256,14 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
# 检查若是被动腿,且已经没有未完成委托,则执行对冲
|
# 检查若是被动腿,且已经没有未完成委托,则执行对冲
|
||||||
if not orderList and vtSymbol in self.passiveVtSymbols:
|
if not orderList and vtSymbol in self.passiveVtSymbols:
|
||||||
self.hedgePassiveLeg(vtSymbol)
|
self.hedgePassiveLeg(vtSymbol)
|
||||||
|
self.writeLog(u'发出新的被动腿%s对冲单' %vtSymbol)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def updateTimer(self):
|
def updateTimer(self):
|
||||||
"""计时更新"""
|
"""计时更新"""
|
||||||
|
if not self.active:
|
||||||
|
return
|
||||||
|
|
||||||
self.quoteCount += 1
|
self.quoteCount += 1
|
||||||
self.hedgeCount += 1
|
self.hedgeCount += 1
|
||||||
|
|
||||||
@ -200,10 +280,14 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
self.hedgeCount = 0
|
self.hedgeCount = 0
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def start(self, mode=MODE_LONGSHORT):
|
def start(self):
|
||||||
"""启动"""
|
"""启动"""
|
||||||
self.mode = mode
|
|
||||||
self.active = True
|
self.active = True
|
||||||
|
|
||||||
|
self.quoteCount = 0
|
||||||
|
self.hedgeCount = 0
|
||||||
|
|
||||||
|
return self.active
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def stop(self):
|
def stop(self):
|
||||||
@ -212,6 +296,8 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
|
|
||||||
self.hedgingTaskDict.clear()
|
self.hedgingTaskDict.clear()
|
||||||
self.cancelAllOrders()
|
self.cancelAllOrders()
|
||||||
|
|
||||||
|
return self.active
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def sendLegOrder(self, leg, legVolume):
|
def sendLegOrder(self, leg, legVolume):
|
||||||
@ -310,6 +396,9 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
self.hedgingTaskDict[leg.vtSymbol] = newHedgingTask
|
self.hedgingTaskDict[leg.vtSymbol] = newHedgingTask
|
||||||
else:
|
else:
|
||||||
self.hedgingTaskDict[leg.vtSymbol] += newHedgingTask
|
self.hedgingTaskDict[leg.vtSymbol] += newHedgingTask
|
||||||
|
|
||||||
|
# 输出日志
|
||||||
|
self.writeLog(u'主动腿%s成交,方向%s,数量%s' %(trade.vtSymbol, trade.direction, trade.volume))
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def newPassiveLegTrade(self, trade):
|
def newPassiveLegTrade(self, trade):
|
||||||
@ -328,6 +417,9 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
if not self.hedgingTaskDict[trade.vtSymbol]:
|
if not self.hedgingTaskDict[trade.vtSymbol]:
|
||||||
del self.hedgingTaskDict[trade.vtSymbol]
|
del self.hedgingTaskDict[trade.vtSymbol]
|
||||||
|
|
||||||
|
# 输出日志
|
||||||
|
self.writeLog(u'被动腿%s成交,方向%s,数量%s' %(trade.vtSymbol, trade.direction, trade.volume))
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def cancelLegOrder(self, vtSymbol):
|
def cancelLegOrder(self, vtSymbol):
|
||||||
"""撤销某条腿的委托"""
|
"""撤销某条腿的委托"""
|
||||||
@ -339,15 +431,27 @@ class SniperAlgo(StAlgoTemplate):
|
|||||||
for vtOrderID in orderList:
|
for vtOrderID in orderList:
|
||||||
self.algoEngine.cancelOrder(vtOrderID)
|
self.algoEngine.cancelOrder(vtOrderID)
|
||||||
|
|
||||||
|
self.writeLog(u'撤单%s的所有委托' %vtSymbol)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def cancelAllOrders(self):
|
def cancelAllOrders(self):
|
||||||
"""撤销全部委托"""
|
"""撤销全部委托"""
|
||||||
for orderList in self.legOrderDict.values():
|
for orderList in self.legOrderDict.values():
|
||||||
for vtOrderID in orderList:
|
for vtOrderID in orderList:
|
||||||
self.algoEngine.cancelOrder(vtOrderID)
|
self.algoEngine.cancelOrder(vtOrderID)
|
||||||
|
|
||||||
|
self.writeLog(u'全部撤单')
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def cancelAllPassiveLegOrders(self):
|
def cancelAllPassiveLegOrders(self):
|
||||||
"""撤销全部被动腿委托"""
|
"""撤销全部被动腿委托"""
|
||||||
|
cancelPassive = False
|
||||||
|
|
||||||
for vtSymbol in self.passiveVtSymbols:
|
for vtSymbol in self.passiveVtSymbols:
|
||||||
self.cancelLegOrder(vtSymbol)
|
if self.legOrderDict[vtSymbol]:
|
||||||
|
self.cancelLegOrder(vtSymbol)
|
||||||
|
cancelPassive = True
|
||||||
|
|
||||||
|
# 只有确实发出撤单委托时,才输出信息
|
||||||
|
if cancelPassive:
|
||||||
|
self.writeLog(u'被动腿全撤')
|
||||||
|
@ -13,6 +13,8 @@ from vnpy.trader.vtConstant import (EMPTY_INT, EMPTY_FLOAT,
|
|||||||
EVENT_SPREADTRADING_TICK = 'eSpreadTradingTick.'
|
EVENT_SPREADTRADING_TICK = 'eSpreadTradingTick.'
|
||||||
EVENT_SPREADTRADING_POS = 'eSpreadTradingPos.'
|
EVENT_SPREADTRADING_POS = 'eSpreadTradingPos.'
|
||||||
EVENT_SPREADTRADING_LOG = 'eSpreadTradingLog'
|
EVENT_SPREADTRADING_LOG = 'eSpreadTradingLog'
|
||||||
|
EVENT_SPREADTRADING_ALGO = 'eSpreadTradingAlgo.'
|
||||||
|
EVENT_SPREADTRADING_ALGOLOG = 'eSpreadTradingAlgoLog'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
import json
|
import json
|
||||||
import traceback
|
import traceback
|
||||||
from copy import copy
|
import shelve
|
||||||
|
|
||||||
from vnpy.event import Event
|
from vnpy.event import Event
|
||||||
from vnpy.trader.vtFunction import getJsonPath
|
from vnpy.trader.vtFunction import getJsonPath, getTempPath
|
||||||
from vnpy.trader.vtEvent import (EVENT_TICK, EVENT_TRADE, EVENT_POSITION,
|
from vnpy.trader.vtEvent import (EVENT_TICK, EVENT_TRADE, EVENT_POSITION,
|
||||||
EVENT_TIMER, EVENT_ORDER)
|
EVENT_TIMER, EVENT_ORDER)
|
||||||
from vnpy.trader.vtObject import (VtSubscribeReq, VtOrderReq,
|
from vnpy.trader.vtObject import (VtSubscribeReq, VtOrderReq,
|
||||||
@ -14,7 +14,9 @@ from vnpy.trader.vtConstant import (DIRECTION_LONG, DIRECTION_SHORT,
|
|||||||
OFFSET_OPEN, OFFSET_CLOSE)
|
OFFSET_OPEN, OFFSET_CLOSE)
|
||||||
|
|
||||||
from .stBase import (StLeg, StSpread, EVENT_SPREADTRADING_TICK,
|
from .stBase import (StLeg, StSpread, EVENT_SPREADTRADING_TICK,
|
||||||
EVENT_SPREADTRADING_POS, EVENT_SPREADTRADING_LOG)
|
EVENT_SPREADTRADING_POS, EVENT_SPREADTRADING_LOG,
|
||||||
|
EVENT_SPREADTRADING_ALGO, EVENT_SPREADTRADING_ALGOLOG)
|
||||||
|
from .stAlgo import SniperAlgo
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -121,6 +123,9 @@ class StDataEngine(object):
|
|||||||
# 初始化价差
|
# 初始化价差
|
||||||
spread.initSpread()
|
spread.initSpread()
|
||||||
|
|
||||||
|
self.putSpreadTickEvent(spread)
|
||||||
|
self.putSpreadPosEvent(spread)
|
||||||
|
|
||||||
# 返回结果
|
# 返回结果
|
||||||
result = True
|
result = True
|
||||||
msg = u'%s价差创建成功' %spread.name
|
msg = u'%s价差创建成功' %spread.name
|
||||||
@ -145,7 +150,12 @@ class StDataEngine(object):
|
|||||||
spread = self.vtSymbolSpreadDict[tick.vtSymbol]
|
spread = self.vtSymbolSpreadDict[tick.vtSymbol]
|
||||||
spread.calculatePrice()
|
spread.calculatePrice()
|
||||||
|
|
||||||
# 推送价差行情更新
|
# 发出事件
|
||||||
|
self.putSpreadTickEvent(spread)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putSpreadTickEvent(self, spread):
|
||||||
|
"""发出价差行情更新事件"""
|
||||||
event1 = Event(EVENT_SPREADTRADING_TICK+spread.name)
|
event1 = Event(EVENT_SPREADTRADING_TICK+spread.name)
|
||||||
event1.dict_['data'] = spread
|
event1.dict_['data'] = spread
|
||||||
self.eventEngine.put(event1)
|
self.eventEngine.put(event1)
|
||||||
@ -215,13 +225,19 @@ class StDataEngine(object):
|
|||||||
spread.calculatePos()
|
spread.calculatePos()
|
||||||
|
|
||||||
# 推送价差持仓更新
|
# 推送价差持仓更新
|
||||||
|
self.putSpreadPosEvent(spread)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putSpreadPosEvent(self, spread):
|
||||||
|
"""发出价差持仓事件"""
|
||||||
event1 = Event(EVENT_SPREADTRADING_POS+spread.name)
|
event1 = Event(EVENT_SPREADTRADING_POS+spread.name)
|
||||||
event1.dict_['data'] = spread
|
event1.dict_['data'] = spread
|
||||||
self.eventEngine.put(event1)
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
event2 = Event(EVENT_SPREADTRADING_POS)
|
event2 = Event(EVENT_SPREADTRADING_POS)
|
||||||
event2.dict_['data'] = spread
|
event2.dict_['data'] = spread
|
||||||
self.eventEngine.put(event2)
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def registerEvent(self):
|
def registerEvent(self):
|
||||||
@ -236,6 +252,7 @@ class StDataEngine(object):
|
|||||||
contract = self.mainEngine.getContract(vtSymbol)
|
contract = self.mainEngine.getContract(vtSymbol)
|
||||||
if not contract:
|
if not contract:
|
||||||
self.writeLog(u'订阅行情失败,找不到该合约%s' %vtSymbol)
|
self.writeLog(u'订阅行情失败,找不到该合约%s' %vtSymbol)
|
||||||
|
return
|
||||||
|
|
||||||
req = VtSubscribeReq()
|
req = VtSubscribeReq()
|
||||||
req.symbol = contract.symbol
|
req.symbol = contract.symbol
|
||||||
@ -254,18 +271,21 @@ class StDataEngine(object):
|
|||||||
self.eventEngine.put(event)
|
self.eventEngine.put(event)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def stop(self):
|
def getAllSpreads(self):
|
||||||
"""停止"""
|
"""获取所有的价差"""
|
||||||
pass
|
return self.spreadDict.values()
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class StAlgoEngine(object):
|
class StAlgoEngine(object):
|
||||||
"""价差算法交易引擎"""
|
"""价差算法交易引擎"""
|
||||||
|
algoFileName = 'SpreadTradingAlgo.vt'
|
||||||
|
algoFilePath = getTempPath(algoFileName)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def __init__(self, mainEngine, eventEngine):
|
def __init__(self, dataEngine, mainEngine, eventEngine):
|
||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
|
self.dataEngine = dataEngine
|
||||||
self.mainEngine = mainEngine
|
self.mainEngine = mainEngine
|
||||||
self.eventEngine = eventEngine
|
self.eventEngine = eventEngine
|
||||||
|
|
||||||
@ -387,6 +407,122 @@ class StAlgoEngine(object):
|
|||||||
vtOrderID = self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_CLOSE, price, volume, payup)
|
vtOrderID = self.sendOrder(vtSymbol, DIRECTION_LONG, OFFSET_CLOSE, price, volume, payup)
|
||||||
return [vtOrderID]
|
return [vtOrderID]
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def putAlgoEvent(self, algo):
|
||||||
|
"""发出算法状态更新事件"""
|
||||||
|
event = Event(EVENT_SPREADTRADING_ALGO+algo.name)
|
||||||
|
self.eventEngine.put(event)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def writeLog(self, content):
|
||||||
|
"""输出日志"""
|
||||||
|
log = VtLogData()
|
||||||
|
log.logContent = content
|
||||||
|
|
||||||
|
event = Event(EVENT_SPREADTRADING_ALGOLOG)
|
||||||
|
event.dict_['data'] = log
|
||||||
|
|
||||||
|
self.eventEngine.put(event)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def saveSetting(self):
|
||||||
|
"""保存算法配置"""
|
||||||
|
setting = {}
|
||||||
|
for algo in self.algoDict.values():
|
||||||
|
setting[algo.spreadName] = algo.getAlgoParams()
|
||||||
|
|
||||||
|
f = shelve.open(self.algoFilePath)
|
||||||
|
f['setting'] = setting
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def loadSetting(self):
|
||||||
|
"""加载算法配置"""
|
||||||
|
# 创建算法对象
|
||||||
|
l = self.dataEngine.getAllSpreads()
|
||||||
|
for spread in l:
|
||||||
|
self.algoDict[spread.name] = SniperAlgo(self, spread)
|
||||||
|
|
||||||
|
# 加载配置
|
||||||
|
f = shelve.open(self.algoFilePath)
|
||||||
|
setting = f.get('setting', None)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
if not setting:
|
||||||
|
return
|
||||||
|
|
||||||
|
for algo in self.algoDict.values():
|
||||||
|
if algo.spreadName in setting:
|
||||||
|
d = setting[algo.spreadName]
|
||||||
|
algo.setAlgoParams(d)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def stopAll(self):
|
||||||
|
"""停止全部算法"""
|
||||||
|
for algo in self.algoDict.values():
|
||||||
|
algo.stop()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def startAlgo(self, spreadName):
|
||||||
|
"""启动算法"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algoActive = algo.start()
|
||||||
|
return algoActive
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def stopAlgo(self, spreadName):
|
||||||
|
"""停止算法"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algoActive = algo.stop()
|
||||||
|
return algoActive
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def getAllAlgoParams(self):
|
||||||
|
"""获取所有算法的参数"""
|
||||||
|
return [algo.getAlgoParams() for algo in self.algoDict.values()]
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoBuyPrice(self, spreadName, buyPrice):
|
||||||
|
"""设置算法买开价格"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setBuyPrice(buyPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoSellPrice(self, spreadName, sellPrice):
|
||||||
|
"""设置算法卖平价格"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setSellPrice(sellPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoShortPrice(self, spreadName, shortPrice):
|
||||||
|
"""设置算法卖开价格"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setShortPrice(shortPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoCoverPrice(self, spreadName, coverPrice):
|
||||||
|
"""设置算法买平价格"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setCoverPrice(coverPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoMode(self, spreadName, mode):
|
||||||
|
"""设置算法工作模式"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setMode(mode)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoMaxOrderSize(self, spreadName, maxOrderSize):
|
||||||
|
"""设置算法单笔委托限制"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setMaxOrderSize(maxOrderSize)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setAlgoMaxPosSize(self, spreadName, maxPosSize):
|
||||||
|
"""设置算法持仓限制"""
|
||||||
|
algo = self.algoDict[spreadName]
|
||||||
|
algo.setMaxPosSize(maxPosSize)
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class StEngine(object):
|
class StEngine(object):
|
||||||
@ -399,12 +535,21 @@ class StEngine(object):
|
|||||||
self.eventEngine = eventEngine
|
self.eventEngine = eventEngine
|
||||||
|
|
||||||
self.dataEngine = StDataEngine(mainEngine, eventEngine)
|
self.dataEngine = StDataEngine(mainEngine, eventEngine)
|
||||||
self.algoEngine = StAlgoEngine(mainEngine, eventEngine)
|
self.algoEngine = StAlgoEngine(self.dataEngine, mainEngine, eventEngine)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def loadSetting(self):
|
def init(self):
|
||||||
""""""
|
"""初始化"""
|
||||||
self.dataEngine.loadSetting()
|
self.dataEngine.loadSetting()
|
||||||
|
self.algoEngine.loadSetting()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def stop(self):
|
||||||
|
"""停止"""
|
||||||
|
self.dataEngine.saveSetting()
|
||||||
|
|
||||||
|
self.algoEngine.stopAll()
|
||||||
|
self.algoEngine.saveSetting()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,14 +2,20 @@
|
|||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
|
|
||||||
from vnpy.trader.uiQt import QtWidgets
|
from vnpy.event import Event
|
||||||
|
from vnpy.trader.uiQt import QtWidgets, QtCore
|
||||||
from vnpy.trader.uiBasicWidget import (BasicMonitor, BasicCell, PnlCell,
|
from vnpy.trader.uiBasicWidget import (BasicMonitor, BasicCell, PnlCell,
|
||||||
AskCell, BidCell, BASIC_FONT)
|
AskCell, BidCell, BASIC_FONT)
|
||||||
|
|
||||||
from .stBase import (EVENT_SPREADTRADING_TICK, EVENT_SPREADTRADING_POS,
|
from .stBase import (EVENT_SPREADTRADING_TICK, EVENT_SPREADTRADING_POS,
|
||||||
EVENT_SPREADTRADING_LOG)
|
EVENT_SPREADTRADING_LOG, EVENT_SPREADTRADING_ALGO,
|
||||||
|
EVENT_SPREADTRADING_ALGOLOG)
|
||||||
|
from .stAlgo import StAlgoTemplate
|
||||||
|
|
||||||
|
|
||||||
|
STYLESHEET_START = 'background-color: rgb(111,255,244); color: black'
|
||||||
|
STYLESHEET_STOP = 'background-color: rgb(255,201,111); color: black'
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class StTickMonitor(BasicMonitor):
|
class StTickMonitor(BasicMonitor):
|
||||||
@ -64,25 +70,365 @@ class StPosMonitor(BasicMonitor):
|
|||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class StLogMonitor(BasicMonitor):
|
class StLogMonitor(QtWidgets.QTextEdit):
|
||||||
|
"""价差日志监控"""
|
||||||
|
signal = QtCore.pyqtSignal(type(Event()))
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, mainEngine, eventEngine, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StLogMonitor, self).__init__(parent)
|
||||||
|
|
||||||
|
self.eventEngine = eventEngine
|
||||||
|
|
||||||
|
self.registerEvent()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def processLogEvent(self, event):
|
||||||
|
"""处理日志事件"""
|
||||||
|
log = event.dict_['data']
|
||||||
|
content = '%s:%s' %(log.logTime, log.logContent)
|
||||||
|
self.append(content)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def registerEvent(self):
|
||||||
|
"""注册事件监听"""
|
||||||
|
self.signal.connect(self.processLogEvent)
|
||||||
|
|
||||||
|
self.eventEngine.register(EVENT_SPREADTRADING_LOG, self.signal.emit)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StAlgoLogMonitor(BasicMonitor):
|
||||||
"""价差日志监控"""
|
"""价差日志监控"""
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def __init__(self, mainEngine, eventEngine, parent=None):
|
def __init__(self, mainEngine, eventEngine, parent=None):
|
||||||
"""Constructor"""
|
"""Constructor"""
|
||||||
super(StLogMonitor, self).__init__(mainEngine, eventEngine, parent)
|
super(StAlgoLogMonitor, self).__init__(mainEngine, eventEngine, parent)
|
||||||
|
|
||||||
d = OrderedDict()
|
d = OrderedDict()
|
||||||
d['logTime'] = {'chinese':u'时间', 'cellType':BasicCell}
|
d['logTime'] = {'chinese':u'时间', 'cellType':BasicCell}
|
||||||
d['logContent'] = {'chinese':u'日志', 'cellType':BasicCell}
|
d['logContent'] = {'chinese':u'信息', 'cellType':BasicCell}
|
||||||
self.setHeaderDict(d)
|
self.setHeaderDict(d)
|
||||||
|
|
||||||
self.setEventType(EVENT_SPREADTRADING_LOG)
|
self.setEventType(EVENT_SPREADTRADING_ALGOLOG)
|
||||||
self.setFont(BASIC_FONT)
|
self.setFont(BASIC_FONT)
|
||||||
|
|
||||||
self.initTable()
|
self.initTable()
|
||||||
self.registerEvent()
|
self.registerEvent()
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StBuyPriceSpinBox(QtWidgets.QDoubleSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, price, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StBuyPriceSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setDecimals(4)
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(price)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setPrice(self, value):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoBuyPrice(self.spreadName, value)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StSellPriceSpinBox(QtWidgets.QDoubleSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, price, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StSellPriceSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setDecimals(4)
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(price)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setPrice(self, value):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoSellPrice(self.spreadName, value)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StShortPriceSpinBox(QtWidgets.QDoubleSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, price, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StShortPriceSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setDecimals(4)
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(price)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setPrice(self, value):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoShortPrice(self.spreadName, value)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StCoverPriceSpinBox(QtWidgets.QDoubleSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, price, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StCoverPriceSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setDecimals(4)
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(price)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setPrice)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setPrice(self, value):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoCoverPrice(self.spreadName, value)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StMaxPosSizeSpinBox(QtWidgets.QSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, size, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StMaxPosSizeSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(size)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setSize)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setSize(self, size):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoMaxPosSize(self.spreadName, size)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StMaxOrderSizeSpinBox(QtWidgets.QSpinBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, size, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StMaxOrderSizeSpinBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.setRange(-10000, 10000)
|
||||||
|
self.setValue(size)
|
||||||
|
|
||||||
|
self.valueChanged.connect(self.setSize)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setSize(self, size):
|
||||||
|
"""设置价格"""
|
||||||
|
self.algoEngine.setAlgoMaxOrderSize(self.spreadName, size)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StModeComboBox(QtWidgets.QComboBox):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, mode, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StModeComboBox, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
l = [StAlgoTemplate.MODE_LONGSHORT,
|
||||||
|
StAlgoTemplate.MODE_LONGONLY,
|
||||||
|
StAlgoTemplate.MODE_SHORTONLY]
|
||||||
|
self.addItems(l)
|
||||||
|
self.setCurrentIndex(l.index(mode))
|
||||||
|
|
||||||
|
self.currentIndexChanged.connect(self.setMode)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setMode(self):
|
||||||
|
"""设置模式"""
|
||||||
|
mode = unicode(self.currentText())
|
||||||
|
self.algoEngine.setAlgoMode(self.spreadName, mode)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def algoActiveChanged(self, active):
|
||||||
|
"""算法运行状态改变"""
|
||||||
|
# 只允许算法停止时修改运行模式
|
||||||
|
if active:
|
||||||
|
self.setEnabled(False)
|
||||||
|
else:
|
||||||
|
self.setEnabled(True)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StActiveButton(QtWidgets.QPushButton):
|
||||||
|
""""""
|
||||||
|
signalActive = QtCore.pyqtSignal(bool)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, algoEngine, spreadName, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StActiveButton, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = algoEngine
|
||||||
|
self.spreadName = spreadName
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
self.setStopped()
|
||||||
|
|
||||||
|
self.clicked.connect(self.buttonClicked)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def buttonClicked(self):
|
||||||
|
"""改变运行模式"""
|
||||||
|
if self.active:
|
||||||
|
algoActive = self.algoEngine.stopAlgo(self.spreadName)
|
||||||
|
|
||||||
|
if not algoActive:
|
||||||
|
self.setStopped()
|
||||||
|
else:
|
||||||
|
algoActive = self.algoEngine.startAlgo(self.spreadName)
|
||||||
|
|
||||||
|
if algoActive:
|
||||||
|
self.setStarted()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setStarted(self):
|
||||||
|
"""算法启动"""
|
||||||
|
self.setText(u'运行中')
|
||||||
|
self.setStyleSheet(STYLESHEET_START)
|
||||||
|
|
||||||
|
self.active = True
|
||||||
|
self.signalActive.emit(self.active)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def setStopped(self):
|
||||||
|
"""算法停止"""
|
||||||
|
self.setText(u'已停止')
|
||||||
|
self.setStyleSheet(STYLESHEET_STOP)
|
||||||
|
|
||||||
|
self.active = False
|
||||||
|
self.signalActive.emit(self.active)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StAlgoManager(QtWidgets.QTableWidget):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, stEngine, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StAlgoManager, self).__init__(parent)
|
||||||
|
|
||||||
|
self.algoEngine = stEngine.algoEngine
|
||||||
|
|
||||||
|
self.initUi()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initUi(self):
|
||||||
|
"""初始化表格"""
|
||||||
|
headers = [u'价差',
|
||||||
|
u'算法',
|
||||||
|
'BuyPrice',
|
||||||
|
'SellPrice',
|
||||||
|
'CoverPrice',
|
||||||
|
'ShortPrice',
|
||||||
|
u'委托上限',
|
||||||
|
u'持仓上限',
|
||||||
|
u'模式',
|
||||||
|
u'状态']
|
||||||
|
self.setColumnCount(len(headers))
|
||||||
|
self.setHorizontalHeaderLabels(headers)
|
||||||
|
self.horizontalHeader().setResizeMode(QtWidgets.QHeaderView.Stretch)
|
||||||
|
|
||||||
|
self.verticalHeader().setVisible(False)
|
||||||
|
self.setEditTriggers(self.NoEditTriggers)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def initCells(self):
|
||||||
|
"""初始化单元格"""
|
||||||
|
algoEngine = self.algoEngine
|
||||||
|
|
||||||
|
l = self.algoEngine.getAllAlgoParams()
|
||||||
|
self.setRowCount(len(l))
|
||||||
|
|
||||||
|
for row, d in enumerate(l):
|
||||||
|
cellSpreadName = QtWidgets.QTableWidgetItem(d['spreadName'])
|
||||||
|
cellAlgoName = QtWidgets.QTableWidgetItem(d['algoName'])
|
||||||
|
spinBuyPrice = StBuyPriceSpinBox(algoEngine, d['spreadName'], d['buyPrice'])
|
||||||
|
spinSellPrice = StSellPriceSpinBox(algoEngine, d['spreadName'], d['sellPrice'])
|
||||||
|
spinShortPrice = StShortPriceSpinBox(algoEngine, d['spreadName'], d['shortPrice'])
|
||||||
|
spinCoverPrice = StCoverPriceSpinBox(algoEngine, d['spreadName'], d['coverPrice'])
|
||||||
|
spinMaxOrderSize = StMaxOrderSizeSpinBox(algoEngine, d['spreadName'], d['maxOrderSize'])
|
||||||
|
spinMaxPosSize = StMaxPosSizeSpinBox(algoEngine, d['spreadName'], d['maxPosSize'])
|
||||||
|
comboMode = StModeComboBox(algoEngine, d['spreadName'], d['mode'])
|
||||||
|
buttonActive = StActiveButton(algoEngine, d['spreadName'])
|
||||||
|
|
||||||
|
self.setItem(row, 0, cellSpreadName)
|
||||||
|
self.setItem(row, 1, cellAlgoName)
|
||||||
|
self.setCellWidget(row, 2, spinBuyPrice)
|
||||||
|
self.setCellWidget(row, 3, spinSellPrice)
|
||||||
|
self.setCellWidget(row, 4, spinCoverPrice)
|
||||||
|
self.setCellWidget(row, 5, spinShortPrice)
|
||||||
|
self.setCellWidget(row, 6, spinMaxOrderSize)
|
||||||
|
self.setCellWidget(row, 7, spinMaxPosSize)
|
||||||
|
self.setCellWidget(row, 8, comboMode)
|
||||||
|
self.setCellWidget(row, 9, buttonActive)
|
||||||
|
|
||||||
|
buttonActive.signalActive.connect(comboMode.algoActiveChanged)
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class StGroup(QtWidgets.QGroupBox):
|
||||||
|
"""集合显示"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self, widget, title, parent=None):
|
||||||
|
"""Constructor"""
|
||||||
|
super(StGroup, self).__init__(parent)
|
||||||
|
|
||||||
|
self.setTitle(title)
|
||||||
|
vbox = QtWidgets.QVBoxLayout()
|
||||||
|
vbox.addWidget(widget)
|
||||||
|
self.setLayout(vbox)
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class StManager(QtWidgets.QWidget):
|
class StManager(QtWidgets.QWidget):
|
||||||
@ -105,37 +451,48 @@ class StManager(QtWidgets.QWidget):
|
|||||||
self.setWindowTitle(u'价差交易')
|
self.setWindowTitle(u'价差交易')
|
||||||
|
|
||||||
# 创建按钮
|
# 创建按钮
|
||||||
buttonLoadSetting = QtWidgets.QPushButton(u'加载配置')
|
buttonInit = QtWidgets.QPushButton(u'初始化')
|
||||||
|
buttonInit.clicked.connect(self.init)
|
||||||
buttonLoadSetting.clicked.connect(self.stEngine.loadSetting)
|
|
||||||
|
|
||||||
# 创建组件
|
# 创建组件
|
||||||
tickMonitor = StTickMonitor(self.mainEngine, self.eventEngine)
|
tickMonitor = StTickMonitor(self.mainEngine, self.eventEngine)
|
||||||
posMonitor = StPosMonitor(self.mainEngine, self.eventEngine)
|
posMonitor = StPosMonitor(self.mainEngine, self.eventEngine)
|
||||||
logMonitor = StLogMonitor(self.mainEngine, self.eventEngine)
|
logMonitor = StLogMonitor(self.mainEngine, self.eventEngine)
|
||||||
|
self.algoManager = StAlgoManager(self.stEngine)
|
||||||
|
algoLogMonitor = StAlgoLogMonitor(self.mainEngine, self.eventEngine)
|
||||||
|
|
||||||
|
# 创建集合
|
||||||
|
groupTick = StGroup(tickMonitor, u'价差行情')
|
||||||
|
groupPos = StGroup(posMonitor, u'价差持仓')
|
||||||
|
groupLog = StGroup(logMonitor, u'日志信息')
|
||||||
|
groupAlgo = StGroup(self.algoManager, u'价差算法')
|
||||||
|
groupAlgoLog = StGroup(algoLogMonitor, u'算法信息')
|
||||||
|
|
||||||
# 设置布局
|
# 设置布局
|
||||||
hbox1 = QtWidgets.QHBoxLayout()
|
hbox = QtWidgets.QHBoxLayout()
|
||||||
hbox1.addWidget(buttonLoadSetting)
|
hbox.addWidget(buttonInit)
|
||||||
hbox1.addStretch()
|
hbox.addStretch()
|
||||||
|
|
||||||
hbox2 = QtWidgets.QHBoxLayout()
|
grid = QtWidgets.QGridLayout()
|
||||||
hbox2.addWidget(tickMonitor)
|
grid.addLayout(hbox, 0, 0, 1, 2)
|
||||||
hbox2.addWidget(posMonitor)
|
grid.addWidget(groupTick, 1, 0)
|
||||||
|
grid.addWidget(groupPos, 1, 1)
|
||||||
vbox = QtWidgets.QVBoxLayout()
|
grid.addWidget(groupAlgo, 2, 0, 1, 2)
|
||||||
vbox.addLayout(hbox1)
|
grid.addWidget(groupLog, 3, 0)
|
||||||
vbox.addLayout(hbox2)
|
grid.addWidget(groupAlgoLog, 3, 1)
|
||||||
vbox.addWidget(logMonitor)
|
|
||||||
|
self.setLayout(grid)
|
||||||
self.setLayout(vbox)
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def show(self):
|
def show(self):
|
||||||
"""重载显示"""
|
"""重载显示"""
|
||||||
self.showMaximized()
|
self.showMaximized()
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def init(self):
|
||||||
|
"""初始化"""
|
||||||
|
self.stEngine.init()
|
||||||
|
self.algoManager.initCells()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user