549 lines
22 KiB
Python
549 lines
22 KiB
Python
|
# encoding: UTF-8
|
|||
|
|
|||
|
from ctaBase import *
|
|||
|
from vtConstant import *
|
|||
|
import json
|
|||
|
import os
|
|||
|
from datetime import datetime
|
|||
|
|
|||
|
DEBUGCTALOG = True
|
|||
|
|
|||
|
"""
|
|||
|
网格交易,用于套利单
|
|||
|
作者:李来佳,QQ/Wechat:28888502
|
|||
|
ChangeLog:
|
|||
|
0713,修改closeGrid,增加volume字段,关闭网格时,根据价格和交易量进行双重匹配.
|
|||
|
0715,增加保存json和重启后加载本地json文件
|
|||
|
"""
|
|||
|
|
|||
|
class CtaGrid(object):
|
|||
|
"""网格类
|
|||
|
它是网格交易的最小单元
|
|||
|
包括交易方向,开仓价格,平仓价格,止损价格,开仓状态,平仓状态
|
|||
|
|
|||
|
"""
|
|||
|
|
|||
|
def __init__(self, direction, openprice, closeprice, stopprice=EMPTY_FLOAT, volume=1):
|
|||
|
|
|||
|
self.direction = direction # 交易方向
|
|||
|
self.openPrice = openprice # 开仓价格
|
|||
|
self.closePrice = closeprice # 平仓价格
|
|||
|
self.stopPrice = stopprice # 止损价格
|
|||
|
|
|||
|
self.volume = volume # 开仓数量
|
|||
|
self.tradedVolume = EMPTY_INT # 成交数量 开仓时,为开仓数量,平仓时,为平仓数量
|
|||
|
|
|||
|
self.orderStatus = False # 挂单状态: True,已挂单,False,未挂单
|
|||
|
self.orderRef = EMPTY_STRING # OrderId
|
|||
|
self.openStatus = False # 开仓状态
|
|||
|
self.closeStatus = False # 平仓状态
|
|||
|
|
|||
|
self.openDatetime = None
|
|||
|
self.orderDatetime = None # 委托时间
|
|||
|
|
|||
|
def toJson(self):
|
|||
|
"""输出JSON"""
|
|||
|
|
|||
|
j = {}
|
|||
|
j['direction'] = self.direction
|
|||
|
j['openPrice'] = self.openPrice # 开仓价格
|
|||
|
j['closePrice'] = self.closePrice # 平仓价格
|
|||
|
j['stopPrice'] = self.stopPrice # 止损价格
|
|||
|
|
|||
|
j['volume'] = self.volume # 开仓数量
|
|||
|
|
|||
|
j['tradedVolume'] = self.tradedVolume # 成交数量
|
|||
|
|
|||
|
j['orderStatus'] = self.orderStatus # 挂单状态: True,已挂单,False,未挂单
|
|||
|
j['orderRef'] = self.orderRef # OrderId
|
|||
|
j['openStatus'] = self.openStatus # 开仓状态
|
|||
|
j['closeStatus'] = self.closeStatus # 平仓状态
|
|||
|
|
|||
|
if type(self.openDatetime) == type(None):
|
|||
|
j['openDatetime'] = EMPTY_STRING
|
|||
|
else:
|
|||
|
try:
|
|||
|
j['openDatetime'] = self.openDatetime.strftime('%Y-%m-%d %H:%M:%S')
|
|||
|
except Exception:
|
|||
|
j['openDatetime'] = EMPTY_STRING
|
|||
|
|
|||
|
return j
|
|||
|
|
|||
|
def toStr(self):
|
|||
|
"""输入字符串"""
|
|||
|
|
|||
|
str = u'o:{0}/{1};c:{2}/{3},r:{4}/opentime:{5}/ordertime:{6}'\
|
|||
|
.format(self.openPrice, self.openStatus, self.closePrice,
|
|||
|
self.closeStatus, self.orderRef, self.openDatetime, self.orderDatetime)
|
|||
|
return str
|
|||
|
|
|||
|
class CtaGridTrade(object):
|
|||
|
"""网格交易类
|
|||
|
包括两个方向的网格队列,
|
|||
|
"""
|
|||
|
|
|||
|
def __init__(self, strategy, maxlots=5, height=2, win=2, vol=1):
|
|||
|
"""初始化
|
|||
|
maxlots,最大网格数
|
|||
|
height,网格高度(绝对值,包含minDiff)
|
|||
|
win,盈利数(包含minDiff)
|
|||
|
vol,网格开仓数
|
|||
|
"""
|
|||
|
|
|||
|
self.strategy = strategy
|
|||
|
|
|||
|
self.jsonName = self.strategy.name #策略名称
|
|||
|
|
|||
|
self.maxLots = maxlots # 缺省网格数量
|
|||
|
self.gridHeight = height # 最小网格高度(包含minDiff)
|
|||
|
self.gridWin = win # 最小止盈高度(包含minDiff)
|
|||
|
|
|||
|
self.volume = vol # 每次网格开仓数量
|
|||
|
self.volumeList = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] # 梯级开仓数量比例
|
|||
|
|
|||
|
self.upGrids = [] # 上网格列表,专门做空
|
|||
|
self.dnGrids = [] # 下网格列表,专门做多
|
|||
|
|
|||
|
def getVolume(self, gridIndex=EMPTY_INT):
|
|||
|
"""获取网格索引对应的开仓数量比例"""
|
|||
|
|
|||
|
if gridIndex >= len(self.volumeList) or gridIndex < 0:
|
|||
|
return 1
|
|||
|
rate = self.volumeList[gridIndex]
|
|||
|
|
|||
|
if rate == 0:
|
|||
|
return 1
|
|||
|
else:
|
|||
|
return rate
|
|||
|
|
|||
|
def initGrid(self, upline=EMPTY_FLOAT, dnline=EMPTY_FLOAT):
|
|||
|
"""初始化网格队列
|
|||
|
upline,上支撑线
|
|||
|
dnline,下阻力线
|
|||
|
"""
|
|||
|
self.writeCtaLog(u'初始化网格队列,upline:{0},dnline:{1}'.format(upline, dnline))
|
|||
|
# 初始化上网格列表
|
|||
|
if len(self.upGrids) == 0:
|
|||
|
|
|||
|
self.upGrids = self.load(direction= DIRECTION_SHORT)
|
|||
|
|
|||
|
if len(self.upGrids) >0:
|
|||
|
self.writeCtaLog(u'上网格从文件加载完成')
|
|||
|
else:
|
|||
|
# 做空,开仓价为上阻力线+网格高度*i,平仓价为开仓价-止盈高度,开仓数量为缺省
|
|||
|
for i in range(0, self.maxLots, 1):
|
|||
|
grid = CtaGrid(direction=DIRECTION_SHORT,
|
|||
|
openprice=upline+self.gridHeight*i,
|
|||
|
closeprice=upline+self.gridHeight*i-self.gridWin,
|
|||
|
volume=self.volume*self.getVolume(i))
|
|||
|
self.upGrids.append(grid)
|
|||
|
|
|||
|
self.writeCtaLog(u'上网格{0}~{1}初始化完成'.format(upline,upline+self.gridHeight*self.maxLots))
|
|||
|
self.save(direction=DIRECTION_SHORT)
|
|||
|
|
|||
|
|
|||
|
# 初始化下网格列表
|
|||
|
if len(self.dnGrids) == 0:
|
|||
|
|
|||
|
self.dnGrids = self.load(direction= DIRECTION_LONG)
|
|||
|
|
|||
|
if len(self.dnGrids) >0:
|
|||
|
self.writeCtaLog(u'下网格从文件加载完成')
|
|||
|
else:
|
|||
|
|
|||
|
for i in range(0, self.maxLots, 1):
|
|||
|
|
|||
|
# 做多,开仓价为下阻力线-网格高度*i,平仓价为开仓价+止盈高度,开仓数量为缺省
|
|||
|
grid = CtaGrid(direction=DIRECTION_LONG,
|
|||
|
openprice=dnline - self.gridHeight * i,
|
|||
|
closeprice=dnline - self.gridHeight * i + self.gridWin,
|
|||
|
volume=self.volume*self.getVolume(i))
|
|||
|
self.dnGrids.append(grid)
|
|||
|
|
|||
|
self.writeCtaLog(u'下网格{0}~{1}初始化完成'.format(dnline,dnline-self.gridHeight*self.maxLots))
|
|||
|
self.save(direction=DIRECTION_LONG)
|
|||
|
|
|||
|
def writeCtaLog(self, log):
|
|||
|
self.strategy.writeCtaLog(log)
|
|||
|
|
|||
|
def toStr(self,direction):
|
|||
|
"""显示网格"""
|
|||
|
|
|||
|
pendingCloseList = u'' # 平仓清单
|
|||
|
pendingOpenList = u'' # 开仓清单
|
|||
|
deactiveList = u'' # 待激活清单
|
|||
|
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for grid in self.dnGrids:
|
|||
|
# 待平仓
|
|||
|
if grid.openStatus :
|
|||
|
|
|||
|
if grid.tradedVolume == EMPTY_INT:
|
|||
|
pendingCloseList = pendingCloseList + u'[{0}->{1},v:{2}];'\
|
|||
|
.format(grid.openPrice, grid.closePrice, grid.volume)
|
|||
|
else:
|
|||
|
pendingCloseList = pendingCloseList + u'[{0}->{1},v:{2}/{3}];'\
|
|||
|
.format(grid.openPrice, grid.closePrice, grid.volume, grid.tradedVolume)
|
|||
|
|
|||
|
# 待开仓成交
|
|||
|
elif not grid.openStatus and grid.orderStatus:
|
|||
|
if grid.tradedVolume == EMPTY_INT:
|
|||
|
pendingOpenList = pendingOpenList + u'[{0},v:{1}];'.format(grid.openPrice, grid.volume)
|
|||
|
else:
|
|||
|
pendingOpenList = pendingOpenList + u'[{0},v:{1}/{2}];'\
|
|||
|
.format(grid.openPrice, grid.volume, grid.tradedVolume)
|
|||
|
|
|||
|
# 等待挂单
|
|||
|
else:
|
|||
|
deactiveList = deactiveList + u'[{0}];'.format(grid.openPrice)
|
|||
|
|
|||
|
|
|||
|
return u'平:{0};开:{1};待:{2}'.format(pendingCloseList,pendingOpenList,deactiveList)
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for grid in self.upGrids:
|
|||
|
# 待平仓
|
|||
|
if grid.openStatus:
|
|||
|
if grid.tradedVolume == EMPTY_INT:
|
|||
|
pendingCloseList = pendingCloseList + u'[{0}->{1},v:{2}];'\
|
|||
|
.format(grid.openPrice, grid.closePrice, grid.volume)
|
|||
|
else:
|
|||
|
pendingCloseList = pendingCloseList + u'[{0}->{1},v:{2}/{3}];'\
|
|||
|
.format(grid.openPrice, grid.closePrice, grid.volume, grid.tradedVolume)
|
|||
|
|
|||
|
# 待开仓成交
|
|||
|
elif not grid.openStatus and grid.orderStatus:
|
|||
|
if grid.tradedVolume == EMPTY_INT:
|
|||
|
pendingOpenList = pendingOpenList + u'[{0},v:{1}];'.format(grid.openPrice, grid.volume)
|
|||
|
else:
|
|||
|
pendingOpenList = pendingOpenList + u'[{0},v:{1}/{2}];'\
|
|||
|
.format(grid.openPrice, grid.volume, grid.tradedVolume)
|
|||
|
|
|||
|
# 等待挂单
|
|||
|
else:
|
|||
|
deactiveList = deactiveList + u'[{0}];'.format(grid.openPrice)
|
|||
|
|
|||
|
return u'平:{0};开:{1};待:{2}'.format(pendingCloseList,pendingOpenList,deactiveList)
|
|||
|
|
|||
|
def getGrids(self, direction, ordered=False, opened=False, closed=False, begin=EMPTY_FLOAT, end=EMPTY_FLOAT):
|
|||
|
"""获取未挂单的网格
|
|||
|
direction:做多、做空方向: 做多方向时,从dnGrids中获取; 做空方向时,从upGrids中获取
|
|||
|
ordered:是否已提交至服务器
|
|||
|
opened:是否已开仓
|
|||
|
closed:是否已平仓
|
|||
|
begin:开始价格,
|
|||
|
end:结束价格,
|
|||
|
"""
|
|||
|
|
|||
|
# 状态一致,价格大于最低价格
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
if begin == EMPTY_FLOAT: begin = 99999
|
|||
|
if end == EMPTY_FLOAT: end = - 99999
|
|||
|
grids = [x for x in self.dnGrids
|
|||
|
if x.orderStatus == ordered
|
|||
|
and x.openStatus == opened
|
|||
|
and x.closeStatus == closed
|
|||
|
and x.openPrice <= begin
|
|||
|
and x.openPrice >= end]
|
|||
|
|
|||
|
return grids
|
|||
|
|
|||
|
# 状态一致,开仓价格小于最高价格
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
if begin == EMPTY_FLOAT: begin = -99999
|
|||
|
if end == EMPTY_FLOAT: end = 99999
|
|||
|
grids = [x for x in self.upGrids
|
|||
|
if x.orderStatus == ordered
|
|||
|
and x.openStatus == opened
|
|||
|
and x.closeStatus == closed
|
|||
|
and x.openPrice >= begin
|
|||
|
and x.openPrice <= end]
|
|||
|
|
|||
|
return grids
|
|||
|
|
|||
|
def updateOrderRef(self, direction, openPrice, orderRef):
|
|||
|
"""更新网格的orderId"""
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for x in self.dnGrids:
|
|||
|
if x.openPrice == openPrice:
|
|||
|
x.orderRef = orderRef
|
|||
|
x.orderStatus = True
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for x in self.upGrids:
|
|||
|
if x.openPrice == openPrice:
|
|||
|
x.orderRef = orderRef
|
|||
|
x.orderStatus = True
|
|||
|
|
|||
|
def cancelOrderRef(self,direction, openPrice):
|
|||
|
"""网格撤单"""
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for x in self.dnGrids:
|
|||
|
if x.openPrice == openPrice and x.orderRef != EMPTY_STRING and x.orderStatus==True and x.openStatus==False:
|
|||
|
x.orderRef = EMPTY_STRING
|
|||
|
x.orderStatus = False
|
|||
|
self.writeCtaLog(u'下网格撤单[{0}]'.format(x.openPrice))
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for x in self.upGrids:
|
|||
|
if x.openPrice == openPrice and x.orderRef != EMPTY_STRING and x.orderStatus==True and x.openStatus==False:
|
|||
|
x.orderRef = EMPTY_STRING
|
|||
|
x.orderStatus = False
|
|||
|
self.writeCtaLog(u'上网格撤单[{0}]'.format(x.openPrice))
|
|||
|
|
|||
|
def getGrid(self, direction, openPrice=EMPTY_FLOAT, closePrice=EMPTY_FLOAT, orderRef=EMPTY_STRING, t=EMPTY_STRING):
|
|||
|
"""获取网格"""
|
|||
|
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for x in self.dnGrids:
|
|||
|
# 优先匹配价格
|
|||
|
if t == u'OpenPrice' and x.openPrice == openPrice:
|
|||
|
return x
|
|||
|
elif t == u'ClosePrice' and x.closePrice == closePrice:
|
|||
|
return x
|
|||
|
elif t == u'OrderRef' and x.orderRef == orderRef:
|
|||
|
return x
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for x in self.upGrids:
|
|||
|
# 优先匹配价格
|
|||
|
if t == u'OpenPrice' and x.openPrice == openPrice:
|
|||
|
return x
|
|||
|
elif t == u'ClosePrice' and x.closePrice == closePrice:
|
|||
|
return x
|
|||
|
elif t == u'OrderRef' and x.orderRef == orderRef:
|
|||
|
return x
|
|||
|
|
|||
|
self.writeCtaLog(u'异常,找不到网格[{0},{1},{2},{3},{4}]'.format(direction, openPrice, closePrice, orderRef, t))
|
|||
|
return None
|
|||
|
|
|||
|
def closeGrid(self, direction, closePrice, closeVolume):
|
|||
|
"""网格交易结束"""
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for x in self.dnGrids:
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume == closeVolume:
|
|||
|
self.writeCtaLog(u'下网格交易结束[{0}->{1}],仓位:{2},移除网格'.format(x.openPrice, x.closePrice,closeVolume))
|
|||
|
self.dnGrids.remove(x)
|
|||
|
return
|
|||
|
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume > closeVolume:
|
|||
|
self.writeCtaLog(u'下网格交易部分结束[{0}->{1}],减少仓位:{2}'.format(x.openPrice, x.closePrice,closeVolume))
|
|||
|
x.volume = x.volume - closeVolume
|
|||
|
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume < closeVolume:
|
|||
|
self.writeCtaLog(u'下网格交易结束[{0}->{1}],移除网格,剩余仓位:{2}'.format(x.openPrice, x.closePrice, closeVolume-x.volume))
|
|||
|
closeVolume = closeVolume - x.volume
|
|||
|
self.dnGrids.remove(x)
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for x in self.upGrids:
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume == closeVolume:
|
|||
|
self.writeCtaLog(u'上网格交易结束[{0}->{1}],仓位:{2},移除网格'.format(x.openPrice, x.closePrice,closeVolume))
|
|||
|
self.upGrids.remove(x)
|
|||
|
return
|
|||
|
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume > closeVolume:
|
|||
|
self.writeCtaLog(u'上网格交易结束[{0}->{1}],仓位减少:{2}'.format(x.openPrice, x.closePrice,closeVolume))
|
|||
|
x.volume = x.volume - closeVolume
|
|||
|
|
|||
|
if x.closePrice == closePrice and x.openStatus and x.volume < closeVolume:
|
|||
|
self.writeCtaLog(u'上网格交易结束[{0}->{1}],移除网格,剩余仓位:{2}'.format(x.openPrice, x.closePrice,closeVolume-x.volume))
|
|||
|
closeVolume = closeVolume - x.volume
|
|||
|
self.upGrids.remove(x)
|
|||
|
|
|||
|
|
|||
|
def removeGrids(self, direction, priceline):
|
|||
|
"""清除网格"""
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
for x in self.dnGrids[:]:
|
|||
|
if x.openPrice > priceline and not x.orderStatus and not x.openStatus and not x.closeStatus:
|
|||
|
self.writeCtaLog(u'清除下网格[open={0}]'.format(x.openPrice))
|
|||
|
self.dnGrids.remove(x)
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
for x in self.upGrids[:]:
|
|||
|
if x.openPrice < priceline and not x.orderStatus and not x.openStatus and not x.closeStatus:
|
|||
|
self.writeCtaLog(u'清除上网格[open={0}]'.format(x.openPrice))
|
|||
|
self.upGrids.remove(x)
|
|||
|
|
|||
|
def rebuildGrids(self, direction, upline=EMPTY_FLOAT, dnline=EMPTY_FLOAT, midline=EMPTY_FLOAT):
|
|||
|
"""重新拉网
|
|||
|
清除未挂单的网格,
|
|||
|
在上轨/下轨位置重新挂单
|
|||
|
"""
|
|||
|
self.writeCtaLog(u'重新拉网:upline:{0},dnline:{1}'.format(upline, dnline))
|
|||
|
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
minPriceInOrder = midline
|
|||
|
removePrices = []
|
|||
|
# 移除未挂单的下网格
|
|||
|
for x in self.dnGrids[:]:
|
|||
|
if not x.orderStatus and not x.openStatus and not x.closeStatus:
|
|||
|
removePrices.append(x.openPrice)
|
|||
|
self.dnGrids.remove(x)
|
|||
|
else:
|
|||
|
self.writeCtaLog(u'保留网格[open={0}]'.format(x.openPrice))
|
|||
|
if x.openPrice < minPriceInOrder :
|
|||
|
minPriceInOrder = x.openPrice
|
|||
|
|
|||
|
self.writeCtaLog(u'清除下网格[{0}]'.format(removePrices))
|
|||
|
|
|||
|
# 需要重建的剩余网格数量
|
|||
|
remainLots = len(self.dnGrids)
|
|||
|
lots = self.maxLots - remainLots
|
|||
|
|
|||
|
dnline = min(dnline, minPriceInOrder-self.gridHeight)
|
|||
|
self.writeCtaLog(u'需要重建的网格数量:{0},起点:{1}'.format(lots, dnline))
|
|||
|
|
|||
|
if lots > 0:
|
|||
|
|
|||
|
for i in range(0, lots, 1):
|
|||
|
# 做多,开仓价为下阻力线-网格高度*i,平仓价为开仓价+止盈高度,开仓数量为缺省
|
|||
|
grid = CtaGrid(direction=DIRECTION_LONG,
|
|||
|
openprice=dnline - self.gridHeight * i,
|
|||
|
closeprice=dnline - self.gridHeight * i + self.gridWin,
|
|||
|
volume=self.volume*self.getVolume(remainLots+i))
|
|||
|
|
|||
|
self.dnGrids.append(grid)
|
|||
|
self.writeCtaLog(u'重新拉下网格:[{0}~{1}]'.format(dnline, dnline-self.gridHeight * lots))
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
maxPriceInOrder = midline
|
|||
|
removePrices = []
|
|||
|
# 移除未挂单的上网格
|
|||
|
for x in self.upGrids[:]:
|
|||
|
if not x.orderStatus and not x.openStatus and not x.closeStatus:
|
|||
|
removePrices.append(x.openPrice)
|
|||
|
self.upGrids.remove(x)
|
|||
|
else:
|
|||
|
self.writeCtaLog(u'保留网格[open={0}]'.format(x.openPrice))
|
|||
|
if x.openPrice > maxPriceInOrder :
|
|||
|
maxPriceInOrder = x.openPrice
|
|||
|
|
|||
|
self.writeCtaLog(u'清除上网格[{0}]'.format(removePrices))
|
|||
|
|
|||
|
# 需要重建的剩余网格数量
|
|||
|
remainLots = len(self.upGrids)
|
|||
|
lots = self.maxLots - remainLots
|
|||
|
upline = max(upline, maxPriceInOrder+self.gridHeight)
|
|||
|
self.writeCtaLog(u'需要重建的网格数量:{0},起点:{1}'.format(lots, upline))
|
|||
|
|
|||
|
if lots > 0:
|
|||
|
# 做空,开仓价为上阻力线+网格高度*i,平仓价为开仓价-止盈高度,开仓数量为缺省
|
|||
|
for i in range(0, lots, 1):
|
|||
|
grid = CtaGrid(direction=DIRECTION_SHORT,
|
|||
|
openprice=upline+self.gridHeight*i,
|
|||
|
closeprice=upline+self.gridHeight*i-self.gridWin,
|
|||
|
volume=self.volume*self.getVolume(remainLots+i))
|
|||
|
self.upGrids.append(grid)
|
|||
|
|
|||
|
self.writeCtaLog(u'重新拉上网格:[{0}~{1}]'.format(upline, upline+self.gridHeight * lots))
|
|||
|
|
|||
|
def save(self,direction):
|
|||
|
"""保存网格至本地Json文件"""
|
|||
|
|
|||
|
# 保存上网格列表
|
|||
|
if len(self.upGrids) > 0 and direction == DIRECTION_SHORT:
|
|||
|
|
|||
|
jsonFileName = self.jsonName + u'_upGrids.json'
|
|||
|
|
|||
|
l = []
|
|||
|
for grid in self.upGrids:
|
|||
|
l.append(grid.toJson())
|
|||
|
|
|||
|
with open(jsonFileName, 'w') as f:
|
|||
|
|
|||
|
jsonL = json.dumps(l, indent=4)
|
|||
|
f.write(jsonL)
|
|||
|
|
|||
|
#self.writeCtaLog(u'上网格保存文件{0}完成'.format(jsonFileName))
|
|||
|
|
|||
|
# 保存上网格列表
|
|||
|
if len(self.dnGrids) > 0 and direction == DIRECTION_LONG:
|
|||
|
|
|||
|
jsonFileName = self.jsonName + u'_dnGrids.json'
|
|||
|
|
|||
|
l = []
|
|||
|
for grid in self.dnGrids:
|
|||
|
l.append(grid.toJson())
|
|||
|
|
|||
|
with open(jsonFileName, 'w') as f:
|
|||
|
|
|||
|
jsonL = json.dumps(l, indent=4)
|
|||
|
f.write(jsonL)
|
|||
|
|
|||
|
#self.writeCtaLog(u'下网格保存文件{0}完成'.format(jsonFileName))
|
|||
|
|
|||
|
def load(self, direction):
|
|||
|
"""加载本地Json至网格"""
|
|||
|
|
|||
|
if direction == DIRECTION_SHORT:
|
|||
|
jsonFileName = self.jsonName + u'_upGrids.json'
|
|||
|
self.writeCtaLog(u'开始加载上网格文件{0}'.format(jsonFileName))
|
|||
|
if direction == DIRECTION_LONG:
|
|||
|
jsonFileName = self.jsonName + u'_dnGrids.json'
|
|||
|
self.writeCtaLog(u'开始加载上网格文件{0}'.format(jsonFileName))
|
|||
|
|
|||
|
if not os.path.isfile(jsonFileName) :
|
|||
|
self.writeCtaLog(u'网格保存文件{0}不存在'.format(jsonFileName))
|
|||
|
return []
|
|||
|
|
|||
|
try:
|
|||
|
f = file(jsonFileName)
|
|||
|
except IOError:
|
|||
|
self.writeCtaLog(u'读取网格出错,请检查')
|
|||
|
return []
|
|||
|
|
|||
|
# 解析json文件
|
|||
|
l = json.load(f)
|
|||
|
|
|||
|
grids = []
|
|||
|
|
|||
|
if len(l) > 0:
|
|||
|
|
|||
|
for i in l:
|
|||
|
closePrice = float(i['closePrice'])
|
|||
|
openPrice = float(i['openPrice'])
|
|||
|
stopPrice = float(i['stopPrice'])
|
|||
|
|
|||
|
self.writeCtaLog(u'load Grid:open:{0},close:{1},stop:{2}'.format(openPrice, closePrice, stopPrice))
|
|||
|
|
|||
|
grid = CtaGrid(direction=i['direction'], openprice=openPrice, closeprice=closePrice,
|
|||
|
stopprice=stopPrice, volume=i['volume'])
|
|||
|
grid.orderStatus = i['orderStatus'] # 挂单状态: True,已挂单,False,未挂单
|
|||
|
grid.orderRef = i['orderRef'] # OrderId
|
|||
|
grid.openStatus = i['openStatus'] # 开仓状态
|
|||
|
grid.closeStatus = i['closeStatus'] # 平仓状态
|
|||
|
strTime = i['openDatetime']
|
|||
|
if strTime == EMPTY_STRING or type(strTime)==type(None):
|
|||
|
grid.openDatetime = None
|
|||
|
else:
|
|||
|
grid.openDatetime = datetime.strptime(strTime, '%Y-%m-%d %H:%M:%S')
|
|||
|
|
|||
|
try:
|
|||
|
grid.tradedVolume = i['tradedVolume'] # 已交易的合约数量
|
|||
|
except KeyError:
|
|||
|
grid.tradedVolume = EMPTY_INT
|
|||
|
|
|||
|
self.writeCtaLog(grid.toStr())
|
|||
|
|
|||
|
grids.append(grid)
|
|||
|
|
|||
|
else:
|
|||
|
self.writeCtaLog(u'解析网格出错,设置为空列表')
|
|||
|
|
|||
|
f.close()
|
|||
|
return grids
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|