增加CTA引擎内部对于上期所自动区分平今平昨的功能
This commit is contained in:
parent
e352fc38ff
commit
ee3430fb76
@ -2,6 +2,18 @@
|
||||
|
||||
'''
|
||||
本文件中实现了CTA策略引擎,针对CTA类型的策略,抽象简化了部分底层接口的功能。
|
||||
|
||||
关于平今和平昨规则:
|
||||
1. 普通的平仓OFFSET_CLOSET等于平昨OFFSET_CLOSEYESTERDAY
|
||||
2. 只有上期所的品种需要考虑平今和平昨的区别
|
||||
3. 当上期所的期货有今仓时,调用Sell和Cover会使用OFFSET_CLOSETODAY,否则
|
||||
会使用OFFSET_CLOSE
|
||||
4. 以上设计意味着如果Sell和Cover的数量超过今日持仓量时,会导致出错(即用户
|
||||
希望通过一个指令同时平今和平昨)
|
||||
5. 采用以上设计的原因是考虑到vn.trader的用户主要是对TB、MC和金字塔类的平台
|
||||
感到功能不足的用户(即希望更高频的交易),交易策略不应该出现4中所述的情况
|
||||
6. 对于想要实现4中所述情况的用户,需要实现一个策略信号引擎和交易委托引擎分开
|
||||
的定制化统结构(没错,得自己写)
|
||||
'''
|
||||
|
||||
import json
|
||||
@ -54,6 +66,10 @@ class CtaEngine(object):
|
||||
self.stopOrderDict = {} # 停止单撤销后不会从本字典中删除
|
||||
self.workingStopOrderDict = {} # 停止单撤销后会从本字典中删除
|
||||
|
||||
# 持仓缓存字典
|
||||
# key为vtSymbol,value为PositionBuffer对象
|
||||
self.posBufferDict = {}
|
||||
|
||||
# 注册事件监听
|
||||
self.registerEvent()
|
||||
|
||||
@ -78,15 +94,48 @@ class CtaEngine(object):
|
||||
if orderType == CTAORDER_BUY:
|
||||
req.direction = DIRECTION_LONG
|
||||
req.offset = OFFSET_OPEN
|
||||
|
||||
elif orderType == CTAORDER_SELL:
|
||||
req.direction = DIRECTION_SHORT
|
||||
req.offset = OFFSET_CLOSE
|
||||
|
||||
# 只有上期所才要考虑平今平昨
|
||||
if contract.exchange != EXCHANGE_SHFE:
|
||||
req.offset = OFFSET_CLOSE
|
||||
else:
|
||||
# 获取持仓缓存数据
|
||||
posBuffer = self.posBufferDict.get(vtSymbol, None)
|
||||
# 如果获取持仓缓存失败,则默认平昨
|
||||
if not posBuffer:
|
||||
req.offset = OFFSET_CLOSE
|
||||
# 否则如果有多头今仓,则使用平今
|
||||
elif posBuffer.longToday:
|
||||
req.offset= OFFSET_CLOSETODAY
|
||||
# 其他情况使用平昨
|
||||
else:
|
||||
req.offset = OFFSET_CLOSE
|
||||
|
||||
elif orderType == CTAORDER_SHORT:
|
||||
req.direction = DIRECTION_SHORT
|
||||
req.offset = OFFSET_OPEN
|
||||
|
||||
elif orderType == CTAORDER_COVER:
|
||||
req.direction = DIRECTION_LONG
|
||||
req.offset = OFFSET_CLOSE
|
||||
|
||||
# 只有上期所才要考虑平今平昨
|
||||
if contract.exchange != EXCHANGE_SHFE:
|
||||
req.offset = OFFSET_CLOSE
|
||||
else:
|
||||
# 获取持仓缓存数据
|
||||
posBuffer = self.posBufferDict.get(vtSymbol, None)
|
||||
# 如果获取持仓缓存失败,则默认平昨
|
||||
if not posBuffer:
|
||||
req.offset = OFFSET_CLOSE
|
||||
# 否则如果有空头今仓,则使用平今
|
||||
elif posBuffer.shortToday:
|
||||
req.offset= OFFSET_CLOSETODAY
|
||||
# 其他情况使用平昨
|
||||
else:
|
||||
req.offset = OFFSET_CLOSE
|
||||
|
||||
vtOrderID = self.mainEngine.sendOrder(req, contract.gatewayName) # 发单
|
||||
self.orderStrategyDict[vtOrderID] = strategy # 保存vtOrderID和策略的映射关系
|
||||
@ -229,6 +278,29 @@ class CtaEngine(object):
|
||||
strategy.pos -= trade.volume
|
||||
|
||||
strategy.onTrade(trade)
|
||||
|
||||
# 更新持仓缓存数据
|
||||
if trade.vtSymbol in self.tickStrategyDict:
|
||||
posBuffer = self.posBufferDict.get(trade.vtSymbol, None)
|
||||
if not posBuffer:
|
||||
posBuffer = PositionBuffer()
|
||||
posBuffer.vtSymbol = trade.vtSymbol
|
||||
self.posBufferDict[trade.vtSymbol] = posBuffer
|
||||
posBuffer.updateTradeData(trade)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def processPositionEvent(self, event):
|
||||
"""处理持仓推送"""
|
||||
pos = event.dict_['data']
|
||||
|
||||
# 更新持仓缓存数据
|
||||
if pos.vtSymbol in self.tickStrategyDict:
|
||||
posBuffer = self.posBufferDict.get(pos.vtSymbol, None)
|
||||
if not posBuffer:
|
||||
posBuffer = PositionBuffer()
|
||||
posBuffer.vtSymbol = pos.vtSymbol
|
||||
self.posBufferDict[pos.vtSymbol] = posBuffer
|
||||
posBuffer.updatePositionData(pos)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def registerEvent(self):
|
||||
@ -236,6 +308,7 @@ class CtaEngine(object):
|
||||
self.eventEngine.register(EVENT_TICK, self.procecssTickEvent)
|
||||
self.eventEngine.register(EVENT_ORDER, self.processOrderEvent)
|
||||
self.eventEngine.register(EVENT_TRADE, self.processTradeEvent)
|
||||
self.eventEngine.register(EVENT_POSITION, self.processPositionEvent)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def insertData(self, dbName, collectionName, data):
|
||||
@ -442,4 +515,67 @@ class CtaEngine(object):
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
class PositionBuffer(object):
|
||||
"""持仓缓存信息(本地维护的持仓数据)"""
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self):
|
||||
"""Constructor"""
|
||||
self.vtSymbol = EMPTY_STRING
|
||||
|
||||
# 多头
|
||||
self.longPosition = EMPTY_INT
|
||||
self.longToday = EMPTY_INT
|
||||
self.longYd = EMPTY_INT
|
||||
|
||||
# 空头
|
||||
self.shortPosition = EMPTY_INT
|
||||
self.shortToday = EMPTY_INT
|
||||
self.shortYd = EMPTY_INT
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def updatePositionData(self, pos):
|
||||
"""更新持仓数据"""
|
||||
if pos.direction == DIRECTION_LONG:
|
||||
self.longPosition = pos.position
|
||||
self.longYd = pos.ydPosition
|
||||
self.longToday = self.longPosition - self.longYd
|
||||
else:
|
||||
self.shortPosition = pos.position
|
||||
self.shortYd = pos.ydPosition
|
||||
self.shortToday = self.shortPosition - self.shortYd
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def updateTradeData(self, trade):
|
||||
"""更新成交数据"""
|
||||
if trade.direction == DIRECTION_LONG:
|
||||
# 多方开仓,则对应多头的持仓和今仓增加
|
||||
if trade.offset == OFFSET_OPEN:
|
||||
self.longPosition += trade.volume
|
||||
self.longToday += trade.volume
|
||||
# 多方平今,对应空头的持仓和今仓减少
|
||||
elif trade.offset == OFFSET_CLOSETODAY:
|
||||
self.shortPosition -= trade.volume
|
||||
self.shortToday -= trade.volume
|
||||
# 多方平昨,对应空头的持仓和昨仓减少
|
||||
else:
|
||||
self.shortPosition -= trade.volume
|
||||
self.shortYd -= trade.volume
|
||||
else:
|
||||
# 空头和多头相同
|
||||
if trade.offset == OFFSET_OPEN:
|
||||
self.shortPosition += trade.volume
|
||||
self.shortToday += trade.volume
|
||||
elif trade.offset == OFFSET_CLOSETODAY:
|
||||
self.longPosition -= trade.volume
|
||||
self.longToday -= trade.volume
|
||||
else:
|
||||
self.longPosition -= trade.volume
|
||||
self.longYd -= trade.volume
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
vn.trader/ltsGateway/vnltsmd.so
Normal file
BIN
vn.trader/ltsGateway/vnltsmd.so
Normal file
Binary file not shown.
BIN
vn.trader/ltsGateway/vnltsqry.so
Normal file
BIN
vn.trader/ltsGateway/vnltsqry.so
Normal file
Binary file not shown.
BIN
vn.trader/ltsGateway/vnltstd.so
Normal file
BIN
vn.trader/ltsGateway/vnltstd.so
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user