update
This commit is contained in:
parent
341ae7c08e
commit
ccf3bb1b8a
@ -1032,7 +1032,7 @@ class BacktestingEngine(object):
|
|||||||
self.output(u'最大回撤: \t%s' % formatNumber(min(d['drawdownList'])))
|
self.output(u'最大回撤: \t%s' % formatNumber(min(d['drawdownList'])))
|
||||||
|
|
||||||
self.output(u'平均每笔盈利:\t%s' %formatNumber(d['capital']/d['totalResult']))
|
self.output(u'平均每笔盈利:\t%s' %formatNumber(d['capital']/d['totalResult']))
|
||||||
self.output(u'平均每笔滑点:\t%s' %formatNumber(d['totalSlippage']/d['totalResult']))
|
self.output(u'平均每笔滑点成本:\t%s' %formatNumber(d['totalSlippage']/d['totalResult']))
|
||||||
self.output(u'平均每笔佣金:\t%s' %formatNumber(d['totalCommission']/d['totalResult']))
|
self.output(u'平均每笔佣金:\t%s' %formatNumber(d['totalCommission']/d['totalResult']))
|
||||||
|
|
||||||
# 绘图
|
# 绘图
|
||||||
@ -1070,7 +1070,7 @@ class BacktestingEngine(object):
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def setRate(self, rate):
|
def setRate(self, rate):
|
||||||
"""设置佣金比例"""
|
"""设置佣金比例"""
|
||||||
self.rate = rate
|
self.rate = float(rate)
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def runOptimization(self, strategyClass, optimizationSetting):
|
def runOptimization(self, strategyClass, optimizationSetting):
|
||||||
@ -1135,7 +1135,7 @@ class TradingResult(object):
|
|||||||
self.volume = volume # 交易数量(+/-代表方向)
|
self.volume = volume # 交易数量(+/-代表方向)
|
||||||
|
|
||||||
self.turnover = (self.entry+self.exit)*size # 成交金额
|
self.turnover = (self.entry+self.exit)*size # 成交金额
|
||||||
self.commission = self.turnover*rate # 手续费成本
|
self.commission =round(float(self.turnover*rate),4) # 手续费成本
|
||||||
self.slippage = slippage*2*size # 滑点成本
|
self.slippage = slippage*2*size # 滑点成本
|
||||||
self.pnl = ((self.exit - self.entry) * volume * size
|
self.pnl = ((self.exit - self.entry) * volume * size
|
||||||
- self.commission - self.slippage) # 净盈亏
|
- self.commission - self.slippage) # 净盈亏
|
||||||
|
@ -90,7 +90,7 @@ class CtaBarData(object):
|
|||||||
self.low = EMPTY_FLOAT
|
self.low = EMPTY_FLOAT
|
||||||
self.close = EMPTY_FLOAT
|
self.close = EMPTY_FLOAT
|
||||||
|
|
||||||
self.date = EMPTY_STRING # bar开始的时间,日期
|
self.date = EMPTY_STRING # bar开始的时间,日期(通过tick生成的bar时间,为开始时间,其他为结束时间)
|
||||||
self.time = EMPTY_STRING # 时间
|
self.time = EMPTY_STRING # 时间
|
||||||
self.datetime = None # python的datetime时间对象
|
self.datetime = None # python的datetime时间对象
|
||||||
|
|
||||||
@ -103,6 +103,9 @@ class CtaBarData(object):
|
|||||||
# CTAORDER_SHORT 、CTAORDER_COVER 、 CTAORDER_OPEN_REJECT 、
|
# CTAORDER_SHORT 、CTAORDER_COVER 、 CTAORDER_OPEN_REJECT 、
|
||||||
# CTAORDER_OPEN_FAIL 、CTAORDER_CLOSE_FAIL
|
# CTAORDER_OPEN_FAIL 、CTAORDER_CLOSE_FAIL
|
||||||
|
|
||||||
|
self.mid4 = EMPTY_FLOAT # (2*CLOSE+HIGH+LOW)/4;
|
||||||
|
self.mid5 = EMPTY_FLOAT # (2*CLOSE+HIGH+LOW+OPEN)/5
|
||||||
|
|
||||||
self.seconds = EMPTY_INT # 当前Bar的秒数(针对RenkoBar)
|
self.seconds = EMPTY_INT # 当前Bar的秒数(针对RenkoBar)
|
||||||
self.highSeconds = -1 # 当前Bar的上限秒数
|
self.highSeconds = -1 # 当前Bar的上限秒数
|
||||||
self.lowSeconds = -1 # 当前bar的下限秒数
|
self.lowSeconds = -1 # 当前bar的下限秒数
|
||||||
|
@ -254,7 +254,7 @@ class CtaLineBar(object):
|
|||||||
# 与最后一个BAR的时间比对,判断是否超过K线的周期
|
# 与最后一个BAR的时间比对,判断是否超过K线的周期
|
||||||
lastBar = self.lineBar[-1]
|
lastBar = self.lineBar[-1]
|
||||||
|
|
||||||
if (bar.datetime - lastBar.datetime).seconds >= self.barTimeInterval:
|
if abs((bar.datetime - lastBar.datetime).seconds) >= self.barTimeInterval:
|
||||||
self.lineBar.append(bar)
|
self.lineBar.append(bar)
|
||||||
self.onBar(bar)
|
self.onBar(bar)
|
||||||
return
|
return
|
||||||
@ -265,9 +265,15 @@ class CtaLineBar(object):
|
|||||||
lastBar.low = min(lastBar.low, bar.low)
|
lastBar.low = min(lastBar.low, bar.low)
|
||||||
lastBar.volume = lastBar.volume + bar.volume
|
lastBar.volume = lastBar.volume + bar.volume
|
||||||
|
|
||||||
|
lastBar.mid4 = round((2*lastBar.close + lastBar.high+lastBar.low)/4,2)
|
||||||
|
lastBar.mid5 = round((2*lastBar.close + lastBar.open+ lastBar.high+lastBar.low)/5,2)
|
||||||
|
|
||||||
def onBar(self, bar):
|
def onBar(self, bar):
|
||||||
"""OnBar事件"""
|
"""OnBar事件"""
|
||||||
# 计算相关数据
|
# 计算相关数据
|
||||||
|
bar.mid4 = round((2*bar.close + bar.high+bar.low)/4,2)
|
||||||
|
bar.mid5 = round((2*bar.close + bar.open+ bar.high+bar.low)/5,2)
|
||||||
|
|
||||||
self.__recountPreHighLow()
|
self.__recountPreHighLow()
|
||||||
self.__recountMa()
|
self.__recountMa()
|
||||||
self.__recountEma()
|
self.__recountEma()
|
||||||
@ -355,6 +361,10 @@ class CtaLineBar(object):
|
|||||||
self.bar.low = tick.lastPrice
|
self.bar.low = tick.lastPrice
|
||||||
self.bar.close = tick.lastPrice
|
self.bar.close = tick.lastPrice
|
||||||
|
|
||||||
|
self.bar.mid4 = tick.lastPrice # 四价均价
|
||||||
|
self.bar.mid5 = tick.lastPrice # 四价均价
|
||||||
|
|
||||||
|
|
||||||
# K线的日期时间
|
# K线的日期时间
|
||||||
self.bar.date = tick.date # K线的日期时间(去除秒)设为第一个Tick的时间
|
self.bar.date = tick.date # K线的日期时间(去除秒)设为第一个Tick的时间
|
||||||
self.bar.time = tick.time # K线的日期时间(去除秒)设为第一个Tick的时间
|
self.bar.time = tick.time # K线的日期时间(去除秒)设为第一个Tick的时间
|
||||||
@ -379,7 +389,7 @@ class CtaLineBar(object):
|
|||||||
self.onBar(self.bar)
|
self.onBar(self.bar)
|
||||||
return
|
return
|
||||||
|
|
||||||
# 清除8交易小时前的数据,
|
# 清除480周期前的数据,
|
||||||
if l1 > 60 * 8:
|
if l1 > 60 * 8:
|
||||||
del self.lineBar[0]
|
del self.lineBar[0]
|
||||||
|
|
||||||
|
117
vn.trader/ctaAlgo/ctaPosition.py
Normal file
117
vn.trader/ctaAlgo/ctaPosition.py
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# encoding: UTF-8
|
||||||
|
|
||||||
|
from vtConstant import *
|
||||||
|
from ctaBase import *
|
||||||
|
import talib as ta
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
DEBUGCTALOG = True
|
||||||
|
|
||||||
|
class CtaPosition:
|
||||||
|
"""策略的仓位管理类
|
||||||
|
v 0.1 简单的数值,代表多仓数量和空仓数量
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, strategy):
|
||||||
|
self.strategy = strategy
|
||||||
|
|
||||||
|
self.pos = 0 # 持仓状态 0:空仓 >=1 多仓 <=-1 空仓
|
||||||
|
|
||||||
|
self.maxPos = 1 # 最大持仓量
|
||||||
|
|
||||||
|
self.step = 1 # 增仓数量
|
||||||
|
|
||||||
|
self.posList = []
|
||||||
|
|
||||||
|
self.avgPrice = EMPTY_FLOAT
|
||||||
|
|
||||||
|
def avaliablePos2Add(self):
|
||||||
|
"""剩余可加的仓位数量"""
|
||||||
|
|
||||||
|
return self.maxPos - abs(self.pos)
|
||||||
|
|
||||||
|
def openPos(self, direction, vol, price = EMPTY_FLOAT):
|
||||||
|
"""开、加仓"""
|
||||||
|
|
||||||
|
if self.pos == 0:
|
||||||
|
self.posList = []
|
||||||
|
|
||||||
|
if direction == DIRECTION_LONG: # 加多仓
|
||||||
|
|
||||||
|
if self.pos + vol > self.maxPos:
|
||||||
|
self.writeCtaLog(u'异常,超出仓位,当前仓位:{0},加仓:{1},最大仓位:{2}'.format(self.pos,vol,self.maxPos))
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.writeCtaLog(u'仓位:{0}->{1}'.format(self.pos, self.pos+vol))
|
||||||
|
self.pos = self.pos + vol
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
|
||||||
|
|
||||||
|
if direction == DIRECTION_SHORT: # 加空仓
|
||||||
|
|
||||||
|
if self.pos - vol < 0 - self.maxPos:
|
||||||
|
self.writeCtaLog(u'异常,超出仓位,当前仓位:{0},加仓:{1},最大仓位:{2}'.format(self.pos, vol, self.maxPos))
|
||||||
|
return False
|
||||||
|
self.writeCtaLog(u'仓位:{0}->{1}'.format(self.pos, self.pos-vol))
|
||||||
|
self.pos = self.pos - vol
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
|
||||||
|
if price > EMPTY_FLOAT:
|
||||||
|
self.posList.append(price)
|
||||||
|
|
||||||
|
# 计算持仓均价
|
||||||
|
if len(self.posList) > 0:
|
||||||
|
self.avgPrice = sum(self.posList)/len(self.posList)
|
||||||
|
self.avgPrice = round(self.avgPrice, 3)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
def closePos(self, direction, vol):
|
||||||
|
"""平、减仓"""
|
||||||
|
|
||||||
|
if direction == DIRECTION_LONG: # 平空仓 Cover
|
||||||
|
|
||||||
|
if self.pos + vol > 0:
|
||||||
|
self.writeCtaLog(u'异常,超出仓位,当前仓位:{0},平仓:{1}'.format(self.pos,vol))
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.writeCtaLog(u'仓位:{0}->{1}'.format(self.pos, self.pos+vol))
|
||||||
|
self.pos = self.pos + vol
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
|
||||||
|
if direction == DIRECTION_SHORT: # 平多仓
|
||||||
|
|
||||||
|
if self.pos - vol < 0 :
|
||||||
|
self.writeCtaLog(u'异常,超出仓位,当前仓位:{0},加仓:{1}'.format(self.pos, vol))
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
return False
|
||||||
|
|
||||||
|
self.writeCtaLog(u'仓位:{0}->{1}'.format(self.pos, self.pos-vol))
|
||||||
|
self.pos = self.pos - vol
|
||||||
|
self.strategy.pos = self.pos
|
||||||
|
|
||||||
|
if abs(self.pos) > 0:
|
||||||
|
self.posList = self.posList[:-vol]
|
||||||
|
else:
|
||||||
|
self.posList = []
|
||||||
|
|
||||||
|
# 计算持仓均价
|
||||||
|
if len(self.posList) > 0:
|
||||||
|
self.avgPrice = sum(self.posList)/len(self.posList)
|
||||||
|
self.avgPrice = round(self.avgPrice, 3)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
def writeCtaLog(self, content):
|
||||||
|
"""记录CTA日志"""
|
||||||
|
self.strategy.writeCtaLog(content)
|
||||||
|
|
||||||
|
def debugCtaLog(self,content):
|
||||||
|
"""记录CTA日志"""
|
||||||
|
if DEBUGCTALOG:
|
||||||
|
self.strategy.writeCtaLog('[DEBUG]'+content)
|
||||||
|
|
@ -11,8 +11,10 @@
|
|||||||
from ctaTemplate import DataRecorder
|
from ctaTemplate import DataRecorder
|
||||||
from ctaDemo import DoubleEmaDemo
|
from ctaDemo import DoubleEmaDemo
|
||||||
from strategy22_ArbitrageGrid import Strategy22
|
from strategy22_ArbitrageGrid import Strategy22
|
||||||
|
from strategy24_M15RB import Strategy24
|
||||||
|
|
||||||
STRATEGY_CLASS = {}
|
STRATEGY_CLASS = {}
|
||||||
STRATEGY_CLASS['DataRecorder'] = DataRecorder
|
STRATEGY_CLASS['DataRecorder'] = DataRecorder
|
||||||
STRATEGY_CLASS['DoubleEmaDemo'] = DoubleEmaDemo
|
STRATEGY_CLASS['DoubleEmaDemo'] = DoubleEmaDemo
|
||||||
STRATEGY_CLASS['Strategy22'] = Strategy22
|
STRATEGY_CLASS['Strategy22'] = Strategy22
|
||||||
|
STRATEGY_CLASS['Strategy24'] = Strategy24
|
@ -1027,7 +1027,8 @@ class TradingWidget(QtGui.QFrame):
|
|||||||
contract = self.mainEngine.getContract(symbol)
|
contract = self.mainEngine.getContract(symbol)
|
||||||
|
|
||||||
if contract:
|
if contract:
|
||||||
gatewayName = contract.gatewayName
|
if not gatewayName:
|
||||||
|
gatewayName = contract.gatewayName
|
||||||
exchange = contract.exchange # 保证有交易所代码
|
exchange = contract.exchange # 保证有交易所代码
|
||||||
|
|
||||||
req = VtOrderReq()
|
req = VtOrderReq()
|
||||||
|
Loading…
Reference in New Issue
Block a user