sync vnpy1.6.2
This commit is contained in:
parent
a7dd183b30
commit
314023553f
0
vnpy/trader/__init__.py
Normal file
0
vnpy/trader/__init__.py
Normal file
43
vnpy/trader/app/ctaStrategy/CTA_setting.json
Normal file
43
vnpy/trader/app/ctaStrategy/CTA_setting.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
[
|
||||||
|
|
||||||
|
{
|
||||||
|
"name": "S30_RB1001",
|
||||||
|
"className": "Strategy30",
|
||||||
|
"vtSymbol": "rb1710;rb1801",
|
||||||
|
"symbol": "rb1710;rb1801",
|
||||||
|
"shortSymbol":"RB",
|
||||||
|
"Leg1Symbol":"rb1710",
|
||||||
|
"Leg2Symbol":"rb1801",
|
||||||
|
"baseUpLine":300,
|
||||||
|
"baseMidLine":0,
|
||||||
|
"baseDnLine":-300,
|
||||||
|
"minDiff":1,
|
||||||
|
"inputSS":2,
|
||||||
|
"height":3,
|
||||||
|
"win":5,
|
||||||
|
"maxPos":36,
|
||||||
|
"maxLots":15,
|
||||||
|
"mode":"tick"
|
||||||
|
}
|
||||||
|
,
|
||||||
|
{
|
||||||
|
"name": "S30_HCRB10",
|
||||||
|
"className": "Strategy30",
|
||||||
|
"vtSymbol": "hc1710;rb1710",
|
||||||
|
"symbol": "hc1710;rb1710",
|
||||||
|
"shortSymbol":"RB",
|
||||||
|
"Leg1Symbol":"hc1710",
|
||||||
|
"Leg2Symbol":"rb1710",
|
||||||
|
"baseUpLine":300,
|
||||||
|
"baseMidLine":150,
|
||||||
|
"baseDnLine":10,
|
||||||
|
"minDiff":1,
|
||||||
|
"inputSS":2,
|
||||||
|
"height":3,
|
||||||
|
"win":5,
|
||||||
|
"maxPos":36,
|
||||||
|
"maxLots":15,
|
||||||
|
"mode":"tick"
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
@ -662,7 +662,7 @@ class CtaEngine(object):
|
|||||||
# continue
|
# continue
|
||||||
dt = datetime.now()
|
dt = datetime.now()
|
||||||
# 若为中金所的合约,白天才提交订阅请求
|
# 若为中金所的合约,白天才提交订阅请求
|
||||||
if s in MARKET_ZJ and not(8 < dt.hour < 16):
|
if s in MARKET_ZJ and not(9 < dt.hour < 16):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
self.writeCtaLog(u'重新提交合约{0}订阅请求'.format(symbol))
|
self.writeCtaLog(u'重新提交合约{0}订阅请求'.format(symbol))
|
||||||
|
File diff suppressed because it is too large
Load Diff
317
vnpy/trader/app/ctaStrategy/uiSpreadTrade.py
Normal file
317
vnpy/trader/app/ctaStrategy/uiSpreadTrade.py
Normal file
@ -0,0 +1,317 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
'''
|
||||||
|
套利交易模块相关的GUI控制组件
|
||||||
|
'''
|
||||||
|
|
||||||
|
from vnpy.trader.vtConstant import DIRECTION_LONG, DIRECTION_SHORT
|
||||||
|
from vnpy.trader.uiBasicWidget import QtGui, QtCore
|
||||||
|
from vnpy.trader.vtEvent import *
|
||||||
|
from vnpy.trader.app.ctaStrategy.ctaGridTrade import *
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class SplitLine(QtGui.QFrame):
|
||||||
|
"""水平分割线"""
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
def __init__(self):
|
||||||
|
"""Constructor"""
|
||||||
|
super(SplitLine, self).__init__()
|
||||||
|
self.setFrameShape(self.HLine)
|
||||||
|
self.setFrameShadow(self.Sunken)
|
||||||
|
|
||||||
|
class SpreadTradeManager(QtGui.QWidget):
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def __init__(self, ctaEngine, eventEngine, parent=None):
|
||||||
|
super(SpreadTradeManager, self).__init__(parent)
|
||||||
|
self.ctaEngine = ctaEngine
|
||||||
|
self.eventEngine = eventEngine
|
||||||
|
self.strategy_name_list = []
|
||||||
|
self.strategy = None
|
||||||
|
|
||||||
|
self.directionList = [DIRECTION_LONG, DIRECTION_SHORT]
|
||||||
|
self.initUi()
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def initUi(self):
|
||||||
|
"""初始化界面"""
|
||||||
|
self.setWindowTitle(u'套利交易')
|
||||||
|
|
||||||
|
# 连接运行中的套利测试(策略名称[下拉菜单],连接按钮)
|
||||||
|
self.btnSwitchConnectStatus = QtGui.QPushButton(u'套利策略未连接')
|
||||||
|
self.btnSwitchConnectStatus.clicked.connect(self.btnSwitchClick)
|
||||||
|
|
||||||
|
Label = QtGui.QLabel
|
||||||
|
grid = QtGui.QGridLayout()
|
||||||
|
grid.addWidget(Label(u'状态'), 0, 0)
|
||||||
|
grid.addWidget(self.btnSwitchConnectStatus, 0, 1)
|
||||||
|
|
||||||
|
self.spreadStraty = QtGui.QComboBox()
|
||||||
|
self.strategy_name_list = self.ctaEngine.strategyDict.keys()
|
||||||
|
self.spreadStraty.addItems(self.strategy_name_list)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'套利策略'), 1, 0)
|
||||||
|
grid.addWidget(self.spreadStraty, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
|
# 网格信息+操作(新增,删除,更新)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'方向'), 2, 0)
|
||||||
|
self.gridDirection = QtGui.QComboBox()
|
||||||
|
self.gridDirection.addItems(self.directionList)
|
||||||
|
grid.addWidget(self.gridDirection, 2, 1)
|
||||||
|
|
||||||
|
self.spinOpenPrice = QtGui.QDoubleSpinBox()
|
||||||
|
self.spinOpenPrice.setDecimals(4)
|
||||||
|
self.spinOpenPrice.setMinimum(-10000) # 原来是0,为支持套利,改为-10000
|
||||||
|
self.spinOpenPrice.setMaximum(100000)
|
||||||
|
self.spinOpenPrice.valueChanged.connect(self.spinOpenPrice_valueChanged)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'开仓价'), 3, 0)
|
||||||
|
grid.addWidget(self.spinOpenPrice, 3, 1)
|
||||||
|
|
||||||
|
self.spinClosePrice = QtGui.QDoubleSpinBox()
|
||||||
|
self.spinClosePrice.setDecimals(4)
|
||||||
|
self.spinClosePrice.setMinimum(-10000) # 原来是0,为支持套利,改为-10000
|
||||||
|
self.spinClosePrice.setMaximum(100000)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'平仓价'), 4, 0)
|
||||||
|
grid.addWidget(self.spinClosePrice, 4, 1)
|
||||||
|
|
||||||
|
self.spinOrderVolume = QtGui.QSpinBox()
|
||||||
|
self.spinOrderVolume.setMinimum(0)
|
||||||
|
self.spinOrderVolume.setMaximum(1000)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'委托数量'), 5, 0)
|
||||||
|
grid.addWidget(self.spinOrderVolume, 5, 1)
|
||||||
|
|
||||||
|
self.spinTradedVolume = QtGui.QSpinBox()
|
||||||
|
self.spinTradedVolume.setMinimum(0)
|
||||||
|
self.spinTradedVolume.setMaximum(1000)
|
||||||
|
|
||||||
|
grid.addWidget(Label(u'成交数量'), 6, 0)
|
||||||
|
grid.addWidget(self.spinTradedVolume, 6, 1)
|
||||||
|
|
||||||
|
self.openStatus = QtGui.QCheckBox(u'') # 开仓状态
|
||||||
|
grid.addWidget(Label(u'开仓状态'), 7, 0)
|
||||||
|
grid.addWidget(self.openStatus, 7, 1)
|
||||||
|
|
||||||
|
self.orderStatus = QtGui.QCheckBox(u'') # 委托状态
|
||||||
|
grid.addWidget(Label(u'委托状态'), 8, 0)
|
||||||
|
grid.addWidget(self.orderStatus, 8, 1)
|
||||||
|
|
||||||
|
self.closeStatus = QtGui.QCheckBox(u'') # 平仓状态
|
||||||
|
grid.addWidget(Label(u'平仓状态'), 9, 0)
|
||||||
|
grid.addWidget(self.closeStatus, 9, 1)
|
||||||
|
|
||||||
|
btnAddGrid = QtGui.QPushButton(u'增加')
|
||||||
|
btnAddGrid.clicked.connect(self.btnAddGridClick)
|
||||||
|
btnUpdateGrid = QtGui.QPushButton(u'更新')
|
||||||
|
btnUpdateGrid.clicked.connect(self.btnUpdateGridClick)
|
||||||
|
btnRemoveGrid = QtGui.QPushButton(u'删除')
|
||||||
|
btnRemoveGrid.clicked.connect(self.btnRemoveGridClick)
|
||||||
|
btnRemoveAll = QtGui.QPushButton(u'全删除')
|
||||||
|
btnRemoveAll.clicked.connect(self.btnRemoveAllClick)
|
||||||
|
|
||||||
|
hbox = QtGui.QHBoxLayout()
|
||||||
|
hbox.addWidget(btnAddGrid)
|
||||||
|
hbox.addWidget(btnUpdateGrid)
|
||||||
|
hbox.addStretch()
|
||||||
|
hbox.addWidget(btnRemoveGrid)
|
||||||
|
hbox.addWidget(btnRemoveAll)
|
||||||
|
|
||||||
|
vbox = QtGui.QVBoxLayout()
|
||||||
|
vbox.addLayout(grid)
|
||||||
|
vbox.addLayout(hbox)
|
||||||
|
|
||||||
|
|
||||||
|
# 状态信息(通过定时器,显示 上网格清单,下网格清单)
|
||||||
|
|
||||||
|
#日志监控
|
||||||
|
self.logMsgs = QtGui.QTextEdit()
|
||||||
|
self.logMsgs.setReadOnly(True)
|
||||||
|
self.logMsgs.setMaximumHeight(200)
|
||||||
|
vbox.addWidget(self.logMsgs)
|
||||||
|
|
||||||
|
self.setLayout(vbox)
|
||||||
|
|
||||||
|
def btnSwitchClick(self):
|
||||||
|
"""策略连接按钮"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
strategy_name = unicode(self.spreadStraty.currentText())
|
||||||
|
|
||||||
|
if strategy_name is None or len(strategy_name) == 0:
|
||||||
|
if len(self.strategy_name_list)==0:
|
||||||
|
self.strategy_name_list = self.ctaEngine.strategyDict.keys()
|
||||||
|
self.spreadStraty.addItems(self.strategy_name_list)
|
||||||
|
return
|
||||||
|
|
||||||
|
self.strategy = self.ctaEngine.strategyDict[strategy_name]
|
||||||
|
|
||||||
|
if self.strategy.trading:
|
||||||
|
self.btnSwitchConnectStatus.setText(u'连接成功、启动')
|
||||||
|
self.log(u'连接{0}成功、启动'.format(strategy_name))
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.btnSwitchConnectStatus.setText(u'连接成功,未启动')
|
||||||
|
self.log(u'连接{0}成功,但策略未启动'.format(strategy_name))
|
||||||
|
|
||||||
|
self.displayGrids()
|
||||||
|
|
||||||
|
def btnAddGridClick(self):
|
||||||
|
"""网格新增按钮"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.strategy is None:
|
||||||
|
self.log(u'没有连接策略')
|
||||||
|
return
|
||||||
|
|
||||||
|
direction = unicode(self.gridDirection.currentText())
|
||||||
|
if direction is None or len(direction) ==0:
|
||||||
|
self.log(u'先选择方向')
|
||||||
|
return
|
||||||
|
|
||||||
|
open_price = self.spinOpenPrice.value()
|
||||||
|
close_price = self.spinClosePrice.value()
|
||||||
|
if open_price == close_price:
|
||||||
|
self.log(u'开仓价和平仓价不能相同')
|
||||||
|
return
|
||||||
|
|
||||||
|
order_volume = self.spinOrderVolume.value()
|
||||||
|
grid = CtaGrid(direction=direction,
|
||||||
|
openprice=open_price,
|
||||||
|
closeprice=close_price,
|
||||||
|
volume=order_volume)
|
||||||
|
|
||||||
|
if direction == DIRECTION_LONG:
|
||||||
|
self.strategy.gt.dnGrids.append(grid)
|
||||||
|
|
||||||
|
else:
|
||||||
|
self.strategy.gt.upGrids.append(grid)
|
||||||
|
|
||||||
|
self.strategy.gt.save(direction=direction)
|
||||||
|
self.strategy.recheckPositions = True
|
||||||
|
grids_info = self.strategy.gt.toStr(direction=direction)
|
||||||
|
self.log(grids_info)
|
||||||
|
|
||||||
|
def displayGrids(self):
|
||||||
|
up_grids_info = self.strategy.gt.toStr(direction=DIRECTION_SHORT)
|
||||||
|
self.log(up_grids_info)
|
||||||
|
dn_grids_info = self.strategy.gt.toStr(direction=DIRECTION_LONG)
|
||||||
|
self.log(dn_grids_info)
|
||||||
|
|
||||||
|
def spinOpenPrice_valueChanged(self):
|
||||||
|
"""查询网格"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.strategy is None:
|
||||||
|
self.log(u'没有连接策略')
|
||||||
|
return
|
||||||
|
|
||||||
|
direction = unicode(self.gridDirection.currentText())
|
||||||
|
if direction is None or len(direction) == 0:
|
||||||
|
self.log(u'先选择方向');
|
||||||
|
return
|
||||||
|
|
||||||
|
open_price = self.spinOpenPrice.value()
|
||||||
|
grid = self.strategy.gt.getGrid(direction=direction, openPrice=open_price, t=u'OpenPrice')
|
||||||
|
|
||||||
|
if grid is None:
|
||||||
|
self.log(u'没有找到{0}方向的网格:{1}'.format(direction, open_price))
|
||||||
|
return
|
||||||
|
|
||||||
|
self.spinClosePrice.setValue(grid.closePrice)
|
||||||
|
self.spinOrderVolume.setValue(grid.volume)
|
||||||
|
self.spinTradedVolume.setValue(grid.tradedVolume)
|
||||||
|
self.openStatus.setChecked(grid.openStatus)
|
||||||
|
self.orderStatus.setChecked(grid.orderStatus)
|
||||||
|
self.closeStatus.setChecked(grid.closeStatus)
|
||||||
|
|
||||||
|
def btnUpdateGridClick(self):
|
||||||
|
"""更新网格"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.strategy is None:
|
||||||
|
self.log(u'没有连接策略')
|
||||||
|
return
|
||||||
|
|
||||||
|
direction = unicode(self.gridDirection.currentText())
|
||||||
|
if direction is None or len(direction) ==0:
|
||||||
|
self.log(u'先选择方向')
|
||||||
|
return
|
||||||
|
|
||||||
|
open_price = self.spinOpenPrice.value()
|
||||||
|
grid = self.strategy.gt.getGrid(direction=direction, openPrice=open_price, t=u'OpenPrice')
|
||||||
|
|
||||||
|
if grid is None:
|
||||||
|
self.log(u'没有找到{0}方向的网格:{1}'.format(direction,open_price))
|
||||||
|
return
|
||||||
|
|
||||||
|
grid.closePrice = self.spinClosePrice.value()
|
||||||
|
grid.volume = self.spinOrderVolume.value()
|
||||||
|
grid.tradedVolume = self.spinTradedVolume.value()
|
||||||
|
grid.openStatus = self.openStatus.isChecked()
|
||||||
|
grid.orderStatus = self.orderStatus.isChecked()
|
||||||
|
grid.closeStatus = self.closeStatus.isChecked()
|
||||||
|
|
||||||
|
self.strategy.gt.save(direction=direction)
|
||||||
|
self.strategy.recheckPositions = True
|
||||||
|
self.displayGrids()
|
||||||
|
|
||||||
|
def btnRemoveGridClick(self):
|
||||||
|
"""删除网格(指定开仓价以下的废格)"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.strategy is None:
|
||||||
|
self.log(u'没有连接策略')
|
||||||
|
return
|
||||||
|
|
||||||
|
direction = unicode(self.gridDirection.currentText())
|
||||||
|
if direction is None or len(direction) == 0:
|
||||||
|
self.log(u'先选择方向')
|
||||||
|
return
|
||||||
|
|
||||||
|
open_price = self.spinOpenPrice.value()
|
||||||
|
self.strategy.gt.removeGrids(direction=direction, priceline=open_price)
|
||||||
|
self.strategy.gt.save(direction=direction)
|
||||||
|
self.log(u'成功移除{0}方向的网格:{1}'.format(direction,open_price))
|
||||||
|
self.displayGrids()
|
||||||
|
|
||||||
|
def btnRemoveAllClick(self):
|
||||||
|
"""删除所有网格"""
|
||||||
|
if self.ctaEngine is None:
|
||||||
|
self.log(u'没有连接CTA引擎')
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.strategy is None:
|
||||||
|
self.log(u'没有连接策略')
|
||||||
|
return
|
||||||
|
|
||||||
|
direction = unicode(self.gridDirection.currentText())
|
||||||
|
if direction is None or len(direction) == 0:
|
||||||
|
self.log(u'先选择方向')
|
||||||
|
return
|
||||||
|
|
||||||
|
if direction == DIRECTION_LONG:
|
||||||
|
self.strategy.gt.dnGrids = []
|
||||||
|
self.strategy.gt.save(direction=direction)
|
||||||
|
else:
|
||||||
|
self.strategy.gt.upGrids=[]
|
||||||
|
self.strategy.gt.save(direction=direction)
|
||||||
|
|
||||||
|
self.displayGrids()
|
||||||
|
|
||||||
|
def log(self, content):
|
||||||
|
self.logMsgs.append(content)
|
||||||
|
|
@ -3,7 +3,7 @@
|
|||||||
'''
|
'''
|
||||||
动态载入所有的Gateway
|
动态载入所有的Gateway
|
||||||
'''
|
'''
|
||||||
|
"""
|
||||||
import os
|
import os
|
||||||
import importlib
|
import importlib
|
||||||
import traceback
|
import traceback
|
||||||
@ -30,6 +30,7 @@ for load_gateway in load_gateways:
|
|||||||
print u'Load {0} exception:{1}'.format(moduleName, ex)
|
print u'Load {0} exception:{1}'.format(moduleName, ex)
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
"""
|
||||||
"""
|
"""
|
||||||
# 获取目录路径
|
# 获取目录路径
|
||||||
path = os.path.abspath(os.path.dirname(__file__))
|
path = os.path.abspath(os.path.dirname(__file__))
|
15
vnpy/trader/gateway/ctpGateway/__init__.py
Normal file
15
vnpy/trader/gateway/ctpGateway/__init__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
print u'init {0}'.format(os.path.dirname(__file__))
|
||||||
|
from vnpy.trader import vtConstant
|
||||||
|
from ctpGateway import CtpGateway
|
||||||
|
|
||||||
|
|
||||||
|
gatewayClass = CtpGateway
|
||||||
|
gatewayName = 'CTP'
|
||||||
|
gatewayDisplayName = 'CTP'
|
||||||
|
gatewayType = vtConstant.GATEWAYTYPE_FUTURES
|
||||||
|
gatewayQryEnabled = True
|
@ -14,14 +14,13 @@ from copy import copy
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
from vnctpmd import MdApi
|
from vnctpmd import MdApi
|
||||||
from vnctptd import TdApi
|
from vnctptd import TdApi
|
||||||
|
|
||||||
from trader.vtGateway import *
|
from vnpy.trader.vtConstant import *
|
||||||
|
from vnpy.trader.vtGateway import *
|
||||||
from ctpDataType import *
|
from ctpDataType import *
|
||||||
from language import text
|
from vnpy.trader.gateway.ctpGateway.language import text
|
||||||
|
|
||||||
|
|
||||||
# 以下为一些VT类型和CTP类型的映射字典
|
# 以下为一些VT类型和CTP类型的映射字典
|
||||||
# 价格类型映射
|
# 价格类型映射
|
@ -7,9 +7,9 @@ from collections import OrderedDict
|
|||||||
|
|
||||||
from PyQt4 import QtGui, QtCore
|
from PyQt4 import QtGui, QtCore
|
||||||
|
|
||||||
from eventEngine import *
|
from vnpy.trader.vtEvent import *
|
||||||
from vtFunction import *
|
from vnpy.trader.vtFunction import *
|
||||||
from vtGateway import *
|
from vnpy.trader.vtGateway import *
|
||||||
import vtText
|
import vtText
|
||||||
|
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ def loadFont():
|
|||||||
"""载入字体设置"""
|
"""载入字体设置"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from trader.vtGlobal import globalSetting
|
from vnpy.trader.vtGlobal import globalSetting
|
||||||
family = globalSetting['fontFamily']
|
family = globalSetting['fontFamily']
|
||||||
size = globalSetting['fontSize']
|
size = globalSetting['fontSize']
|
||||||
font = QtGui.QFont(family, size)
|
font = QtGui.QFont(family, size)
|
@ -5,10 +5,10 @@
|
|||||||
|
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
from trader.app.ctaStrategy.uiCtaWidget import CtaEngineManager
|
from vnpy.trader.app.ctaStrategy.uiCtaWidget import CtaEngineManager
|
||||||
from trader.app.dataRecorder.uiDrWidget import DrEngineManager
|
from vnpy.trader.app.dataRecorder.uiDrWidget import DrEngineManager
|
||||||
from trader.app.riskManager.uiRmWidget import RmEngineManager
|
from vnpy.trader.app.riskManager.uiRmWidget import RmEngineManager
|
||||||
from uiBasicWidget import *
|
from vnpy.trader.uiBasicWidget import *
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
class MainWindow(QtGui.QMainWindow):
|
class MainWindow(QtGui.QMainWindow):
|
||||||
@ -141,8 +141,8 @@ class MainWindow(QtGui.QMainWindow):
|
|||||||
ctaAction = QtGui.QAction(u'CTA策略', self)
|
ctaAction = QtGui.QAction(u'CTA策略', self)
|
||||||
ctaAction.triggered.connect(self.openCta)
|
ctaAction.triggered.connect(self.openCta)
|
||||||
|
|
||||||
#monitorAction = QtGui.QAction(u'周期监控', self)
|
spreadAction = QtGui.QAction(u'套利交易', self)
|
||||||
#monitorAction.triggered.connect(self.openMonitor)
|
spreadAction.triggered.connect(self.openSpread)
|
||||||
|
|
||||||
#kChart = QtGui.QAction(u'K线图', self)
|
#kChart = QtGui.QAction(u'K线图', self)
|
||||||
#kChart.triggered.connect(self.openKChart)
|
#kChart.triggered.connect(self.openKChart)
|
||||||
@ -197,7 +197,7 @@ class MainWindow(QtGui.QMainWindow):
|
|||||||
# 算法相关
|
# 算法相关
|
||||||
algoMenu = menubar.addMenu(u'算法')
|
algoMenu = menubar.addMenu(u'算法')
|
||||||
algoMenu.addAction(ctaAction)
|
algoMenu.addAction(ctaAction)
|
||||||
#algoMenu.addAction(monitorAction)
|
algoMenu.addAction(spreadAction)
|
||||||
#algoMenu.addAction(kChart)
|
#algoMenu.addAction(kChart)
|
||||||
|
|
||||||
# 帮助
|
# 帮助
|
||||||
@ -494,6 +494,21 @@ class MainWindow(QtGui.QMainWindow):
|
|||||||
self.widgetDict['rmM'] = RmEngineManager(self.mainEngine.rmEngine, self.eventEngine)
|
self.widgetDict['rmM'] = RmEngineManager(self.mainEngine.rmEngine, self.eventEngine)
|
||||||
self.widgetDict['rmM'].show()
|
self.widgetDict['rmM'].show()
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def openSpread(self):
|
||||||
|
"""打开SpreadTrade组件"""
|
||||||
|
|
||||||
|
if 'spread' in self.widgetDict:
|
||||||
|
self.widgetDict['spread'].show()
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
from vnpy.trader.app.ctaStrategy.uiSpreadTrade import SpreadTradeManager
|
||||||
|
self.widgetDict['spread'] = SpreadTradeManager(self.mainEngine.ctaEngine, self.eventEngine)
|
||||||
|
self.widgetDict['spread'].show()
|
||||||
|
except Exception as ex:
|
||||||
|
return
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def closeEvent(self, event):
|
def closeEvent(self, event):
|
||||||
"""关闭事件"""
|
"""关闭事件"""
|
@ -6,7 +6,7 @@ from __future__ import print_function
|
|||||||
import requests
|
import requests
|
||||||
import execjs
|
import execjs
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from trader.app.ctaStrategy.ctaBase import CtaBarData, CtaTickData
|
from vnpy.trader.app.ctaStrategy.ctaBase import CtaBarData, CtaTickData
|
||||||
|
|
||||||
class UtilSinaClient(object):
|
class UtilSinaClient(object):
|
||||||
|
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
@ -4,11 +4,11 @@ import ctypes
|
|||||||
import platform
|
import platform
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from vnrpc import RpcClient
|
from vnpy.rpc import RpcClient
|
||||||
|
|
||||||
from trader.app.ctaStrategy.ctaEngine import CtaEngine
|
from vnpy.trader.app.ctaStrategy.ctaEngine import CtaEngine
|
||||||
from trader.app.dataRecorder.drEngine import DrEngine
|
from vnpy.trader.app.dataRecorder.drEngine import DrEngine
|
||||||
from trader.app.riskManager.rmEngine import RmEngine
|
from vnpy.trader.app.riskManager.rmEngine import RmEngine
|
||||||
from uiMainWindow import *
|
from uiMainWindow import *
|
||||||
|
|
||||||
# 文件路径名
|
# 文件路径名
|
||||||
@ -175,7 +175,7 @@ def main():
|
|||||||
|
|
||||||
# 设置Qt的皮肤
|
# 设置Qt的皮肤
|
||||||
try:
|
try:
|
||||||
from trader.vtGlobal import globalSetting
|
from vnpy.trader.vtGlobal import globalSetting
|
||||||
|
|
||||||
if globalSetting['darkStyle']:
|
if globalSetting['darkStyle']:
|
||||||
import qdarkstyle
|
import qdarkstyle
|
@ -1,6 +1,6 @@
|
|||||||
# encoding: UTF-8
|
# encoding: UTF-8
|
||||||
|
|
||||||
print 'laoding vntrader.vtConstant'
|
print 'laoding vnpy.trader.vtConstant'
|
||||||
|
|
||||||
# 默认空值
|
# 默认空值
|
||||||
EMPTY_STRING = ''
|
EMPTY_STRING = ''
|
||||||
@ -14,7 +14,7 @@ COLOR_BLUE = u'Blue' # 下降K线
|
|||||||
COLOR_EQUAL = u'Equal' # 平K线
|
COLOR_EQUAL = u'Equal' # 平K线
|
||||||
|
|
||||||
|
|
||||||
from language import constant
|
from vnpy.trader.language import constant
|
||||||
|
|
||||||
# 将常量定义添加到vtConstant.py的局部字典中
|
# 将常量定义添加到vtConstant.py的局部字典中
|
||||||
d = locals()
|
d = locals()
|
@ -6,13 +6,13 @@ from collections import OrderedDict
|
|||||||
from pymongo import MongoClient
|
from pymongo import MongoClient
|
||||||
from pymongo.errors import ConnectionFailure
|
from pymongo.errors import ConnectionFailure
|
||||||
|
|
||||||
from gateway import GATEWAY_DICT
|
from vnpy.trader.vtGlobal import globalSetting
|
||||||
from language import text
|
from vnpy.trader.language import text
|
||||||
from trader.app.ctaStrategy.ctaEngine import CtaEngine
|
from vnpy.trader.app.ctaStrategy.ctaEngine import CtaEngine
|
||||||
from trader.app.dataRecorder.drEngine import DrEngine
|
from vnpy.trader.app.dataRecorder.drEngine import DrEngine
|
||||||
from trader.app.riskManager.rmEngine import RmEngine
|
from vnpy.trader.app.riskManager.rmEngine import RmEngine
|
||||||
from vtFunction import loadMongoSetting
|
from vnpy.trader.vtFunction import loadMongoSetting
|
||||||
from vtGateway import *
|
from vnpy.trader.vtGateway import *
|
||||||
|
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
@ -35,40 +35,43 @@ class MainEngine(object):
|
|||||||
# MongoDB数据库相关
|
# MongoDB数据库相关
|
||||||
self.dbClient = None # MongoDB客户端对象
|
self.dbClient = None # MongoDB客户端对象
|
||||||
|
|
||||||
# 调用一个个初始化函数
|
# 接口实例
|
||||||
self.initGateway()
|
self.gatewayDict = OrderedDict()
|
||||||
|
self.gatewayDetailList = []
|
||||||
|
|
||||||
|
# 应用模块实例
|
||||||
|
self.appDict = OrderedDict()
|
||||||
|
self.appDetailList = []
|
||||||
|
|
||||||
# 扩展模块
|
# 扩展模块
|
||||||
self.ctaEngine = CtaEngine(self, self.eventEngine) # cta策略运行模块
|
self.ctaEngine = CtaEngine(self, self.eventEngine) # cta策略运行模块
|
||||||
self.drEngine = DrEngine(self, self.eventEngine) # 数据记录模块
|
self.drEngine = DrEngine(self, self.eventEngine) # 数据记录模块
|
||||||
self.rmEngine = RmEngine(self, self.eventEngine) # 风险管理模块
|
self.rmEngine = RmEngine(self, self.eventEngine) # 风险管理模块
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
def initGateway(self):
|
def addGateway(self, gatewayModule,gateway_name=EMPTY_STRING):
|
||||||
"""初始化接口对象"""
|
"""添加底层接口"""
|
||||||
# 用来保存接口对象的字典
|
# 是否使用指定的gateway_name
|
||||||
self.gatewayDict = OrderedDict()
|
if gateway_name==EMPTY_STRING:
|
||||||
|
gatewayName = gatewayModule.gatewayName
|
||||||
|
else:
|
||||||
|
gatewayName = gateway_name
|
||||||
|
|
||||||
# 初始化的接口模块,以及其指定的名称,CTP是模块,value,是该模块下的多个连接配置文件,如 CTP_JR_connect.json
|
# 创建接口实例
|
||||||
init_gateway_names = {'CTP': ['CTP', 'CTP_Prod', 'CTP_Post', 'CTP_EBF', 'CTP_JR', 'CTP_JR2']}
|
self.gatewayDict[gatewayName] = gatewayModule.gatewayClass(self.eventEngine,
|
||||||
|
gatewayName)
|
||||||
|
|
||||||
# 遍历接口字典并自动创建所有的接口对象
|
# 设置接口轮询
|
||||||
for gatewayModule in GATEWAY_DICT.values():
|
if gatewayModule.gatewayQryEnabled:
|
||||||
try:
|
self.gatewayDict[gatewayName].setQryEnabled(gatewayModule.gatewayQryEnabled)
|
||||||
if gatewayModule.gatewayName not in init_gateway_names:
|
|
||||||
continue
|
|
||||||
|
|
||||||
for gw_name in init_gateway_names[gatewayModule.gatewayName]:
|
# 保存接口详细信息
|
||||||
self.addGateway(gatewayModule.gateway,gw_name)
|
d = {
|
||||||
if gatewayModule.gatewayQryEnabled:
|
'gatewayName': gatewayModule.gatewayName,
|
||||||
self.gatewayDict[gw_name].setQryEnabled(True)
|
'gatewayDisplayName': gatewayModule.gatewayDisplayName,
|
||||||
except Exception, e:
|
'gatewayType': gatewayModule.gatewayType
|
||||||
print e
|
}
|
||||||
|
self.gatewayDetailList.append(d)
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def addGateway(self, gateway, gatewayName=None):
|
|
||||||
"""创建接口"""
|
|
||||||
self.gatewayDict[gatewayName] = gateway(self.eventEngine, gatewayName)
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
def connect(self, gatewayName):
|
def connect(self, gatewayName):
|
@ -11,6 +11,8 @@
|
|||||||
建议将所有的常量定义放在该文件中,便于检查是否存在重复的现象。
|
建议将所有的常量定义放在该文件中,便于检查是否存在重复的现象。
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
from vnpy.event import *
|
||||||
|
|
||||||
# 系统相关
|
# 系统相关
|
||||||
EVENT_TIMER = 'eTimer' # 计时器事件,每隔1秒发送一次
|
EVENT_TIMER = 'eTimer' # 计时器事件,每隔1秒发送一次
|
||||||
EVENT_LOG = 'eLog' # 日志事件,全局通用
|
EVENT_LOG = 'eLog' # 日志事件,全局通用
|
||||||
@ -38,32 +40,3 @@ EVENT_DATARECORDER_LOG = 'eDataRecorderLog' # 行情记录日志更新事件
|
|||||||
|
|
||||||
# Wind接口相关
|
# Wind接口相关
|
||||||
EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件
|
EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
|
||||||
def test():
|
|
||||||
"""检查是否存在内容重复的常量定义"""
|
|
||||||
check_dict = {}
|
|
||||||
|
|
||||||
global_dict = globals()
|
|
||||||
|
|
||||||
for key, value in global_dict.items():
|
|
||||||
if '__' not in key: # 不检查python内置对象
|
|
||||||
if value in check_dict:
|
|
||||||
check_dict[value].append(key)
|
|
||||||
else:
|
|
||||||
check_dict[value] = [key]
|
|
||||||
|
|
||||||
for key, value in check_dict.items():
|
|
||||||
if len(value)>1:
|
|
||||||
print u'存在重复的常量定义:' + str(key)
|
|
||||||
for name in value:
|
|
||||||
print name
|
|
||||||
print ''
|
|
||||||
|
|
||||||
print u'测试完毕'
|
|
||||||
|
|
||||||
|
|
||||||
# 直接运行脚本可以进行测试
|
|
||||||
if __name__ == '__main__':
|
|
||||||
test()
|
|
@ -33,7 +33,7 @@ def loadMongoSetting():
|
|||||||
"""载入MongoDB数据库的配置"""
|
"""载入MongoDB数据库的配置"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from trader.vtGlobal import globalSetting
|
from vnpy.trader.vtGlobal import globalSetting
|
||||||
host = globalSetting['mongoHost']
|
host = globalSetting['mongoHost']
|
||||||
port = globalSetting['mongoPort']
|
port = globalSetting['mongoPort']
|
||||||
logging = globalSetting['mongoLogging']
|
logging = globalSetting['mongoLogging']
|
166
vnpy/trader/vtGateway.py
Normal file
166
vnpy/trader/vtGateway.py
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
import time
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
from vnpy.trader.vtEvent import *
|
||||||
|
from vnpy.trader.vtConstant import *
|
||||||
|
from vnpy.trader.vtObject import *
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
class VtGateway(object):
|
||||||
|
"""交易接口"""
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def __init__(self, eventEngine, gatewayName):
|
||||||
|
"""Constructor"""
|
||||||
|
self.eventEngine = eventEngine
|
||||||
|
self.gatewayName = gatewayName
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onTick(self, tick):
|
||||||
|
"""市场行情推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_TICK)
|
||||||
|
event1.dict_['data'] = tick
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 特定合约代码的事件
|
||||||
|
event2 = Event(type_=EVENT_TICK+tick.vtSymbol)
|
||||||
|
event2.dict_['data'] = tick
|
||||||
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onTrade(self, trade):
|
||||||
|
"""成交信息推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_TRADE)
|
||||||
|
event1.dict_['data'] = trade
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 特定合约的成交事件
|
||||||
|
event2 = Event(type_=EVENT_TRADE+trade.vtSymbol)
|
||||||
|
event2.dict_['data'] = trade
|
||||||
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onOrder(self, order):
|
||||||
|
"""订单变化推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_ORDER)
|
||||||
|
event1.dict_['data'] = order
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 特定订单编号的事件
|
||||||
|
event2 = Event(type_=EVENT_ORDER+order.vtOrderID)
|
||||||
|
event2.dict_['data'] = order
|
||||||
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onPosition(self, position):
|
||||||
|
"""持仓信息推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_POSITION)
|
||||||
|
event1.dict_['data'] = position
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 特定合约代码的事件
|
||||||
|
event2 = Event(type_=EVENT_POSITION+position.vtSymbol)
|
||||||
|
event2.dict_['data'] = position
|
||||||
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onAccount(self, account):
|
||||||
|
"""账户信息推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_ACCOUNT)
|
||||||
|
event1.dict_['data'] = account
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 特定合约代码的事件
|
||||||
|
event2 = Event(type_=EVENT_ACCOUNT+account.vtAccountID)
|
||||||
|
event2.dict_['data'] = account
|
||||||
|
self.eventEngine.put(event2)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onError(self, error):
|
||||||
|
"""错误信息推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_ERROR)
|
||||||
|
event1.dict_['data'] = error
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
logMsg = u'{0}:[{1}]:{2}'.format(error.gatewayName, error.errorID,error.errorMsg )
|
||||||
|
# 写入本地log日志
|
||||||
|
logging.info(logMsg)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onLog(self, log):
|
||||||
|
"""日志推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_LOG)
|
||||||
|
event1.dict_['data'] = log
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# 写入本地log日志
|
||||||
|
logging.info(log.logContent)
|
||||||
|
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def onContract(self, contract):
|
||||||
|
"""合约基础信息推送"""
|
||||||
|
# 通用事件
|
||||||
|
event1 = Event(type_=EVENT_CONTRACT)
|
||||||
|
event1.dict_['data'] = contract
|
||||||
|
self.eventEngine.put(event1)
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def connect(self):
|
||||||
|
"""连接"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def subscribe(self, subscribeReq):
|
||||||
|
"""订阅行情"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def sendOrder(self, orderReq):
|
||||||
|
"""发单"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def cancelOrder(self, cancelOrderReq):
|
||||||
|
"""撤单"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def qryAccount(self):
|
||||||
|
"""查询账户资金"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def qryPosition(self):
|
||||||
|
"""查询持仓"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def checkStatus(self):
|
||||||
|
"""查询状态"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def close(self):
|
||||||
|
"""关闭"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -8,7 +8,6 @@ import os
|
|||||||
import traceback
|
import traceback
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
globalSetting = {} # 全局配置字典
|
globalSetting = {} # 全局配置字典
|
||||||
|
|
||||||
settingFileName = "VT_setting.json"
|
settingFileName = "VT_setting.json"
|
@ -6,8 +6,13 @@ import ctypes
|
|||||||
import platform
|
import platform
|
||||||
|
|
||||||
import vtPath
|
import vtPath
|
||||||
from vtEngine import MainEngine
|
from vnpy.trader.vtEngine import MainEngine
|
||||||
from uiMainWindow import *
|
from vnpy.trader.uiMainWindow import *
|
||||||
|
# 加载底层接口
|
||||||
|
from vnpy.trader.gateway import ctpGateway
|
||||||
|
|
||||||
|
# 初始化的接口模块,以及其指定的名称,CTP是模块,value,是该模块下的多个连接配置文件,如 CTP_JR_connect.json
|
||||||
|
init_gateway_names = {'CTP': ['CTP', 'CTP_Prod', 'CTP_Post', 'CTP_EBF', 'CTP_JR', 'CTP_JR2']}
|
||||||
|
|
||||||
# 文件路径名
|
# 文件路径名
|
||||||
path = os.path.abspath(os.path.dirname(__file__))
|
path = os.path.abspath(os.path.dirname(__file__))
|
||||||
@ -35,7 +40,7 @@ def main():
|
|||||||
|
|
||||||
# 设置Qt的皮肤
|
# 设置Qt的皮肤
|
||||||
try:
|
try:
|
||||||
from trader.vtGlobal import globalSetting
|
from vnpy.trader.vtGlobal import globalSetting
|
||||||
if globalSetting['darkStyle']:
|
if globalSetting['darkStyle']:
|
||||||
import qdarkstyle
|
import qdarkstyle
|
||||||
app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
|
app.setStyleSheet(qdarkstyle.load_stylesheet(pyside=False))
|
||||||
@ -45,6 +50,10 @@ def main():
|
|||||||
|
|
||||||
# 初始化主引擎和主窗口对象
|
# 初始化主引擎和主窗口对象
|
||||||
mainEngine = MainEngine()
|
mainEngine = MainEngine()
|
||||||
|
|
||||||
|
for gw_name in init_gateway_names['CTP']:
|
||||||
|
mainEngine.addGateway(ctpGateway, gw_name)
|
||||||
|
|
||||||
mainWindow = MainWindow(mainEngine, mainEngine.eventEngine)
|
mainWindow = MainWindow(mainEngine, mainEngine.eventEngine)
|
||||||
mainWindow.showMaximized()
|
mainWindow.showMaximized()
|
||||||
|
|
@ -8,7 +8,7 @@ from time import sleep
|
|||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
import vtPath
|
import vtPath
|
||||||
import eventType
|
import vtEvent
|
||||||
from vnrpc import RpcServer
|
from vnrpc import RpcServer
|
||||||
from vtEngine import MainEngine
|
from vtEngine import MainEngine
|
||||||
|
|
Loading…
Reference in New Issue
Block a user