添加VnTrader中的价差交易模块,完成价差行情的自动计算和显示
This commit is contained in:
parent
83fe273188
commit
8c167c392e
@ -18,7 +18,7 @@ from vnpy.trader.gateway import (ctpGateway, femasGateway, xspeedGateway,
|
||||
|
||||
# 加载上层应用
|
||||
from vnpy.trader.app import (riskManager, dataRecorder,
|
||||
ctaStrategy)
|
||||
ctaStrategy, spreadTrading)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
@ -45,6 +45,7 @@ def main():
|
||||
me.addApp(riskManager)
|
||||
me.addApp(dataRecorder)
|
||||
me.addApp(ctaStrategy)
|
||||
me.addApp(spreadTrading)
|
||||
|
||||
# 创建主窗口
|
||||
mw = MainWindow(me, ee)
|
||||
|
@ -33,6 +33,10 @@ MINUTE_DB_NAME = 'VnTrader_1Min_Db'
|
||||
ENGINETYPE_BACKTESTING = 'backtesting' # 回测
|
||||
ENGINETYPE_TRADING = 'trading' # 实盘
|
||||
|
||||
# CTA模块事件
|
||||
EVENT_CTA_LOG = 'eCtaLog' # CTA相关的日志事件
|
||||
EVENT_CTA_STRATEGY = 'eCtaStrategy.' # CTA策略状态变化事件
|
||||
|
||||
# CTA引擎中涉及的数据类定义
|
||||
from vnpy.trader.vtConstant import EMPTY_UNICODE, EMPTY_STRING, EMPTY_FLOAT, EMPTY_INT
|
||||
|
||||
|
@ -12,6 +12,8 @@ TICK_DB_NAME = 'VnTrader_Tick_Db'
|
||||
DAILY_DB_NAME = 'VnTrader_Daily_Db'
|
||||
MINUTE_DB_NAME = 'VnTrader_1Min_Db'
|
||||
|
||||
# 行情记录模块事件
|
||||
EVENT_DATARECORDER_LOG = 'eDataRecorderLog' # 行情记录日志更新事件
|
||||
|
||||
# CTA引擎中涉及的数据类定义
|
||||
from vnpy.trader.vtConstant import EMPTY_UNICODE, EMPTY_STRING, EMPTY_FLOAT, EMPTY_INT
|
||||
|
64
vnpy/trader/app/spreadTrading/ST_setting.json
Normal file
64
vnpy/trader/app/spreadTrading/ST_setting.json
Normal file
@ -0,0 +1,64 @@
|
||||
[
|
||||
{
|
||||
"name": "IF.07-09",
|
||||
|
||||
"activeLeg":
|
||||
{
|
||||
"vtSymbol": "IF1707",
|
||||
"ratio": 1,
|
||||
"multiplier": 1.0,
|
||||
"payup": 2
|
||||
},
|
||||
|
||||
"passiveLegs": [
|
||||
{
|
||||
"vtSymbol": "IF1709",
|
||||
"ratio": -1,
|
||||
"multiplier": -1.0,
|
||||
"payup": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "IH.07-09",
|
||||
|
||||
"activeLeg":
|
||||
{
|
||||
"vtSymbol": "IH1707",
|
||||
"ratio": 1,
|
||||
"multiplier": 1.0,
|
||||
"payup": 2
|
||||
},
|
||||
|
||||
"passiveLegs": [
|
||||
{
|
||||
"vtSymbol": "IH1709",
|
||||
"ratio": -1,
|
||||
"multiplier": -1.0,
|
||||
"payup": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"name": "IC.07-09",
|
||||
|
||||
"activeLeg":
|
||||
{
|
||||
"vtSymbol": "IC1707",
|
||||
"ratio": 1,
|
||||
"multiplier": 1.0,
|
||||
"payup": 2
|
||||
},
|
||||
|
||||
"passiveLegs": [
|
||||
{
|
||||
"vtSymbol": "IC1709",
|
||||
"ratio": -1,
|
||||
"multiplier": -1.0,
|
||||
"payup": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
10
vnpy/trader/app/spreadTrading/__init__.py
Normal file
10
vnpy/trader/app/spreadTrading/__init__.py
Normal file
@ -0,0 +1,10 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from .stEngine import StEngine
|
||||
from .uiStWidget import StManager
|
||||
|
||||
appName = 'SpreadTrading'
|
||||
appDisplayName = u'价差交易'
|
||||
appEngine = StEngine
|
||||
appWidget = StManager
|
||||
appIco = 'st.ico'
|
BIN
vnpy/trader/app/spreadTrading/st.ico
Normal file
BIN
vnpy/trader/app/spreadTrading/st.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
162
vnpy/trader/app/spreadTrading/stBase.py
Normal file
162
vnpy/trader/app/spreadTrading/stBase.py
Normal file
@ -0,0 +1,162 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from math import floor
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.trader.vtConstant import (EMPTY_INT, EMPTY_FLOAT,
|
||||
EMPTY_STRING, EMPTY_UNICODE)
|
||||
|
||||
|
||||
|
||||
EVENT_SPREADTRADING_TICK = 'eSpreadTradingTick.'
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class StLeg(object):
|
||||
""""""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.vtSymbol = EMPTY_STRING # 代码
|
||||
self.ratio = EMPTY_INT # 实际交易时的比例
|
||||
self.multiplier = EMPTY_FLOAT # 计算价差时的乘数
|
||||
self.payup = EMPTY_INT # 对冲时的超价tick
|
||||
|
||||
self.bidPrice = EMPTY_FLOAT
|
||||
self.askPrice = EMPTY_FLOAT
|
||||
self.bidVolume = EMPTY_INT
|
||||
self.askVolume = EMPTY_INT
|
||||
|
||||
self.longPos = EMPTY_INT
|
||||
self.shortPos = EMPTY_INT
|
||||
self.netPos = EMPTY_INT
|
||||
|
||||
|
||||
########################################################################
|
||||
class StSpread(object):
|
||||
""""""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.name = EMPTY_UNICODE # 名称
|
||||
self.symbol = EMPTY_STRING # 代码(基于组成腿计算)
|
||||
|
||||
self.activeLeg = None # 主动腿
|
||||
self.passiveLegs = [] # 被动腿(支持多条)
|
||||
self.allLegs = [] # 所有腿
|
||||
|
||||
self.bidPrice = EMPTY_FLOAT
|
||||
self.askPrice = EMPTY_FLOAT
|
||||
self.bidVolume = EMPTY_INT
|
||||
self.askVolume = EMPTY_INT
|
||||
self.time = EMPTY_STRING
|
||||
|
||||
self.longPos = EMPTY_INT
|
||||
self.shortPos = EMPTY_INT
|
||||
self.netPos = EMPTY_INT
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initSpread(self):
|
||||
"""初始化价差"""
|
||||
# 价差最少要有一条主动腿
|
||||
if not self.activeLeg:
|
||||
return
|
||||
|
||||
# 生成所有腿列表
|
||||
self.allLegs.append(self.activeLeg)
|
||||
self.allLegs.extend(self.passiveLegs)
|
||||
|
||||
# 生成价差代码
|
||||
legSymbolList = []
|
||||
|
||||
for leg in self.allLegs:
|
||||
if leg.multiplier >= 0:
|
||||
legSymbol = '+%s*%s' %(leg.multiplier, leg.vtSymbol)
|
||||
else:
|
||||
legSymbol = '%s*%s' %(leg.multiplier, leg.vtSymbol)
|
||||
legSymbolList.append(legSymbol)
|
||||
|
||||
self.symbol = ''.join(legSymbolList)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def calculatePrice(self):
|
||||
"""计算价格"""
|
||||
# 清空价格和委托量数据
|
||||
self.bidPrice = EMPTY_FLOAT
|
||||
self.askPrice = EMPTY_FLOAT
|
||||
self.askVolume = EMPTY_INT
|
||||
self.bidVolume = EMPTY_INT
|
||||
|
||||
# 遍历价差腿列表
|
||||
for n, leg in enumerate(self.allLegs):
|
||||
# 计算价格
|
||||
if leg.multiplier > 0:
|
||||
self.bidPrice += leg.bidPrice * leg.multiplier
|
||||
self.askPrice += leg.askPrice * leg.multiplier
|
||||
else:
|
||||
self.bidPrice += leg.askPrice * leg.multiplier
|
||||
self.askPrice += leg.bidPrice * leg.multiplier
|
||||
|
||||
# 计算报单量
|
||||
if leg.ratio > 0:
|
||||
legAdjustedBidVolume = floor(leg.bidVolume / leg.ratio)
|
||||
legAdjustedAskVolume = floor(leg.askVolume / leg.ratio)
|
||||
else:
|
||||
legAdjustedBidVolume = floor(leg.askVolume / abs(leg.ratio))
|
||||
legAdjustedAskVolume = floor(leg.bidVolume / abs(leg.ratio))
|
||||
|
||||
if n == 0:
|
||||
self.bidVolume = legAdjustedBidVolume # 对于第一条腿,直接初始化
|
||||
self.askVolume = legAdjustedAskVolume
|
||||
else:
|
||||
self.bidVolume = min(self.bidVolume, legAdjustedBidVolume) # 对于后续的腿,价差可交易报单量取较小值
|
||||
self.askVolume = min(self.askVolume, legAdjustedAskVolume)
|
||||
|
||||
# 更新时间
|
||||
self.time = datetime.now().strftime('%H:%M:%S.%f')[:-3]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def calculatePos(self):
|
||||
"""计算持仓"""
|
||||
# 清空持仓数据
|
||||
self.longPos = EMPTY_INT
|
||||
self.shortPos = EMPTY_INT
|
||||
self.netPos = EMPTY_INT
|
||||
|
||||
# 遍历价差腿列表
|
||||
for n, leg in enumerate(self.allLegs):
|
||||
if leg.ratio > 0:
|
||||
legAdjustedLongPos = floor(leg.longPos / leg.ratio)
|
||||
legAdjustedShortPos = floor(leg.shortPos / leg.ratio)
|
||||
else:
|
||||
legAdjustedLongPos = floor(leg.shortPos / abs(leg.ratio))
|
||||
legAdjustedShortPos = floor(leg.longPos / abs(leg.ratio))
|
||||
|
||||
if n == 0:
|
||||
self.longPos = legAdjustedLongPos
|
||||
self.shortPos = legAdjustedShortPos
|
||||
else:
|
||||
self.longPos = min(self.longPos, legAdjustedLongPos)
|
||||
self.shortPos = min(self.shortPos, legAdjustedShortPos)
|
||||
|
||||
# 计算净仓位
|
||||
self.netPos = self.longPos - self.shortPos
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def addActiveLeg(self, leg):
|
||||
"""添加主动腿"""
|
||||
self.activeLeg = leg
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def addPassiveLeg(self, leg):
|
||||
"""添加被动腿"""
|
||||
self.passiveLegs.append(leg)
|
||||
|
||||
|
||||
|
||||
|
176
vnpy/trader/app/spreadTrading/stEngine.py
Normal file
176
vnpy/trader/app/spreadTrading/stEngine.py
Normal file
@ -0,0 +1,176 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
import json
|
||||
from copy import copy
|
||||
|
||||
from vnpy.event import Event
|
||||
from vnpy.trader.vtFunction import getJsonPath
|
||||
from vnpy.trader.vtEvent import EVENT_TICK, EVENT_TRADE, EVENT_POSITION
|
||||
from vnpy.trader.vtObject import VtSubscribeReq
|
||||
|
||||
from .stBase import StLeg, StSpread, EVENT_SPREADTRADING_TICK
|
||||
|
||||
|
||||
########################################################################
|
||||
class StEngine(object):
|
||||
""""""
|
||||
settingFileName = 'ST_setting.json'
|
||||
settingFilePath = getJsonPath(settingFileName, __file__)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, mainEngine, eventEngine):
|
||||
"""Constructor"""
|
||||
self.mainEngine = mainEngine
|
||||
self.eventEngine = eventEngine
|
||||
|
||||
# 腿、价差相关字典
|
||||
self.legDict = {} # vtSymbol:StLeg
|
||||
self.spreadDict = {} # name:StSpread
|
||||
self.vtSymbolSpreadDict = {} # vtSymbol:StSpread
|
||||
|
||||
self.registerEvent()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def loadSetting(self):
|
||||
"""加载配置"""
|
||||
with open(self.settingFilePath) as f:
|
||||
l = json.load(f)
|
||||
|
||||
for setting in l:
|
||||
self.createSpread(setting)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def saveSetting(self):
|
||||
"""保存配置"""
|
||||
with open(self.settingFilePath) as f:
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def createSpread(self, setting):
|
||||
"""创建价差"""
|
||||
result = False
|
||||
msg = ''
|
||||
|
||||
# 检查价差重名
|
||||
if setting['name'] in self.spreadDict:
|
||||
msg = u'%s价差重名' %setting['name']
|
||||
return result, msg
|
||||
|
||||
# 检查腿是否已使用
|
||||
l = []
|
||||
l.append(setting['activeLeg']['vtSymbol'])
|
||||
for d in setting['passiveLegs']:
|
||||
l.append(d['vtSymbol'])
|
||||
|
||||
for vtSymbol in l:
|
||||
if vtSymbol in self.vtSymbolSpreadDict:
|
||||
existingSpread = self.vtSymbolSpreadDict[vtSymbol]
|
||||
msg = u'%s合约已经存在于%s价差中' %(vtSymbol, existingSpread.name)
|
||||
return result, msg
|
||||
|
||||
# 创建价差
|
||||
spread = StSpread()
|
||||
spread.name = setting['name']
|
||||
self.spreadDict[spread.name] = spread
|
||||
|
||||
# 创建主动腿
|
||||
activeSetting = setting['activeLeg']
|
||||
|
||||
activeLeg = StLeg()
|
||||
activeLeg.vtSymbol = activeSetting['vtSymbol']
|
||||
activeLeg.ratio = activeSetting['ratio']
|
||||
activeLeg.multiplier = activeSetting['multiplier']
|
||||
activeLeg.payup = activeSetting['payup']
|
||||
|
||||
spread.addActiveLeg(activeLeg)
|
||||
self.legDict[activeLeg.vtSymbol] = activeLeg
|
||||
self.vtSymbolSpreadDict[activeLeg.vtSymbol] = spread
|
||||
|
||||
self.subscribeMarketData(activeLeg.vtSymbol)
|
||||
|
||||
# 创建被动腿
|
||||
passiveSettingList = setting['passiveLegs']
|
||||
passiveLegList = []
|
||||
|
||||
for d in passiveSettingList:
|
||||
passiveLeg = StLeg()
|
||||
passiveLeg.vtSymbol = d['vtSymbol']
|
||||
passiveLeg.ratio = d['ratio']
|
||||
passiveLeg.multiplier = d['multiplier']
|
||||
passiveLeg.payup = d['payup']
|
||||
|
||||
spread.addPassiveLeg(passiveLeg)
|
||||
self.legDict[passiveLeg.vtSymbol] = passiveLeg
|
||||
self.vtSymbolSpreadDict[passiveLeg.vtSymbol] = spread
|
||||
|
||||
self.subscribeMarketData(passiveLeg.vtSymbol)
|
||||
|
||||
# 初始化价差
|
||||
spread.initSpread()
|
||||
|
||||
# 返回结果
|
||||
result = True
|
||||
msg = u'%s价差创建成功' %spread.name
|
||||
return result, msg
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processTickEvent(self, event):
|
||||
"""处理行情推送"""
|
||||
# 检查行情是否需要处理
|
||||
tick = event.dict_['data']
|
||||
if tick.vtSymbol not in self.legDict:
|
||||
return
|
||||
|
||||
# 更新腿价格
|
||||
leg = self.legDict[tick.vtSymbol]
|
||||
leg.bidPrice = tick.bidPrice1
|
||||
leg.askPrice = tick.askPrice1
|
||||
leg.bidVolume = tick.bidVolume1
|
||||
leg.askVolume = tick.askVolume1
|
||||
|
||||
# 更新价差价格
|
||||
spread = self.vtSymbolSpreadDict[tick.vtSymbol]
|
||||
spread.calculatePrice()
|
||||
|
||||
# 推送价差更新
|
||||
newSpread = copy(spread)
|
||||
event = Event(EVENT_SPREADTRADING_TICK)
|
||||
event.dict_['data'] = newSpread
|
||||
self.eventEngine.put(event)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processTradeEvent(self, event):
|
||||
""""""
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processPositionEvent(self, event):
|
||||
""""""
|
||||
pass
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
""""""
|
||||
self.eventEngine.register(EVENT_TICK, self.processTickEvent)
|
||||
self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
|
||||
self.eventEngine.register(EVENT_POSITION, self.processPositionEvent)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def subscribeMarketData(self, vtSymbol):
|
||||
"""订阅行情"""
|
||||
contract = self.mainEngine.getContract(vtSymbol)
|
||||
if not contract:
|
||||
return
|
||||
|
||||
req = VtSubscribeReq()
|
||||
req.symbol = contract.symbol
|
||||
req.exchange = contract.exchange
|
||||
|
||||
self.mainEngine.subscribe(req, contract.gatewayName)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def stop(self):
|
||||
"""停止"""
|
||||
pass
|
||||
|
||||
|
97
vnpy/trader/app/spreadTrading/uiStWidget.py
Normal file
97
vnpy/trader/app/spreadTrading/uiStWidget.py
Normal file
@ -0,0 +1,97 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
from collections import OrderedDict
|
||||
|
||||
from vnpy.trader.uiQt import QtWidgets
|
||||
from vnpy.trader.uiBasicWidget import (BasicMonitor, BasicCell,
|
||||
AskCell, BidCell, BASIC_FONT)
|
||||
|
||||
from .stBase import EVENT_SPREADTRADING_TICK
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class StTickMonitor(BasicMonitor):
|
||||
""""""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, mainEngine, eventEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(StTickMonitor, self).__init__(mainEngine, eventEngine, parent)
|
||||
|
||||
# 设置表头有序字典
|
||||
d = OrderedDict()
|
||||
d['name'] = {'chinese':u'价差名称', 'cellType':BasicCell}
|
||||
d['bidPrice'] = {'chinese':u'买价', 'cellType':BidCell}
|
||||
d['bidVolume'] = {'chinese':u'买量', 'cellType':BidCell}
|
||||
d['askPrice'] = {'chinese':u'卖价', 'cellType':AskCell}
|
||||
d['askVolume'] = {'chinese':u'卖量', 'cellType':AskCell}
|
||||
d['time'] = {'chinese':u'时间', 'cellType':BasicCell}
|
||||
d['symbol'] = {'chinese':u'代码', 'cellType':BasicCell}
|
||||
self.setHeaderDict(d)
|
||||
|
||||
# 设置数据键
|
||||
self.setDataKey('name')
|
||||
|
||||
# 设置监控事件类型
|
||||
self.setEventType(EVENT_SPREADTRADING_TICK)
|
||||
|
||||
# 设置字体
|
||||
self.setFont(BASIC_FONT)
|
||||
|
||||
# 初始化表格
|
||||
self.initTable()
|
||||
|
||||
# 注册事件监听
|
||||
self.registerEvent()
|
||||
|
||||
|
||||
########################################################################
|
||||
class StManager(QtWidgets.QWidget):
|
||||
""""""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, stEngine, eventEngine, parent=None):
|
||||
"""Constructor"""
|
||||
super(StManager, self).__init__(parent)
|
||||
|
||||
self.stEngine = stEngine
|
||||
self.mainEngine = stEngine.mainEngine
|
||||
self.eventEngine = eventEngine
|
||||
|
||||
self.initUi()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def initUi(self):
|
||||
"""初始化界面"""
|
||||
self.setWindowTitle(u'价差交易')
|
||||
|
||||
# 创建按钮
|
||||
buttonLoadSetting = QtWidgets.QPushButton(u'加载配置')
|
||||
|
||||
buttonLoadSetting.clicked.connect(self.stEngine.loadSetting)
|
||||
|
||||
# 创建组件
|
||||
tickMonitor = StTickMonitor(self.mainEngine, self.eventEngine)
|
||||
|
||||
# 设置布局
|
||||
hbox = QtWidgets.QHBoxLayout()
|
||||
hbox.addWidget(buttonLoadSetting)
|
||||
hbox.addStretch()
|
||||
|
||||
vbox = QtWidgets.QVBoxLayout()
|
||||
vbox.addLayout(hbox)
|
||||
vbox.addWidget(tickMonitor)
|
||||
|
||||
self.setLayout(vbox)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def show(self):
|
||||
"""重载显示"""
|
||||
self.showMaximized()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -92,8 +92,6 @@ class CtpGateway(VtGateway):
|
||||
|
||||
self.qryEnabled = False # 循环查询
|
||||
|
||||
self.requireAuthentication = False
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def connect(self):
|
||||
"""连接"""
|
||||
|
@ -26,6 +26,9 @@ exchangeMap[EXCHANGE_CZCE] = 'CZC'
|
||||
exchangeMap[EXCHANGE_UNKNOWN] = ''
|
||||
exchangeMapReverse = {v:k for k,v in exchangeMap.items()}
|
||||
|
||||
# Wind接口相关事件
|
||||
EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件
|
||||
|
||||
|
||||
########################################################################
|
||||
class WindGateway(VtGateway):
|
||||
|
@ -18,13 +18,3 @@ EVENT_POSITION = 'ePosition.' # 持仓回报事件
|
||||
EVENT_ACCOUNT = 'eAccount.' # 账户回报事件
|
||||
EVENT_CONTRACT = 'eContract.' # 合约基础信息回报事件
|
||||
EVENT_ERROR = 'eError.' # 错误回报事件
|
||||
|
||||
# CTA模块相关
|
||||
EVENT_CTA_LOG = 'eCtaLog' # CTA相关的日志事件
|
||||
EVENT_CTA_STRATEGY = 'eCtaStrategy.' # CTA策略状态变化事件
|
||||
|
||||
# 行情记录模块相关
|
||||
EVENT_DATARECORDER_LOG = 'eDataRecorderLog' # 行情记录日志更新事件
|
||||
|
||||
# Wind接口相关
|
||||
EVENT_WIND_CONNECTREQ = 'eWindConnectReq' # Wind接口请求连接事件
|
@ -64,5 +64,20 @@ def getTempPath(name):
|
||||
path = os.path.join(tempPath, name)
|
||||
return path
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def getJsonPath(name, moduleFile):
|
||||
"""
|
||||
获取JSON配置文件的路径:
|
||||
1. 优先从当前工作目录查找JSON文件
|
||||
2. 若无法找到则前往模块所在目录查找
|
||||
"""
|
||||
currentFolder = os.getcwd()
|
||||
currentJsonPath = os.path.join(currentFolder, name)
|
||||
if os.path.isfile(currentJsonPath):
|
||||
return currentJsonPath
|
||||
|
||||
moduleFolder = os.path.abspath(os.path.dirname(moduleFile))
|
||||
moduleJsonPath = os.path.join(moduleFolder, '.', name)
|
||||
return moduleJsonPath
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user