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(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']))
|
||||
|
||||
# 绘图
|
||||
@ -1070,7 +1070,7 @@ class BacktestingEngine(object):
|
||||
#----------------------------------------------------------------------
|
||||
def setRate(self, rate):
|
||||
"""设置佣金比例"""
|
||||
self.rate = rate
|
||||
self.rate = float(rate)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def runOptimization(self, strategyClass, optimizationSetting):
|
||||
@ -1135,7 +1135,7 @@ class TradingResult(object):
|
||||
self.volume = volume # 交易数量(+/-代表方向)
|
||||
|
||||
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.pnl = ((self.exit - self.entry) * volume * size
|
||||
- self.commission - self.slippage) # 净盈亏
|
||||
|
@ -90,7 +90,7 @@ class CtaBarData(object):
|
||||
self.low = EMPTY_FLOAT
|
||||
self.close = EMPTY_FLOAT
|
||||
|
||||
self.date = EMPTY_STRING # bar开始的时间,日期
|
||||
self.date = EMPTY_STRING # bar开始的时间,日期(通过tick生成的bar时间,为开始时间,其他为结束时间)
|
||||
self.time = EMPTY_STRING # 时间
|
||||
self.datetime = None # python的datetime时间对象
|
||||
|
||||
@ -103,6 +103,9 @@ class CtaBarData(object):
|
||||
# CTAORDER_SHORT 、CTAORDER_COVER 、 CTAORDER_OPEN_REJECT 、
|
||||
# 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.highSeconds = -1 # 当前Bar的上限秒数
|
||||
self.lowSeconds = -1 # 当前bar的下限秒数
|
||||
|
@ -254,7 +254,7 @@ class CtaLineBar(object):
|
||||
# 与最后一个BAR的时间比对,判断是否超过K线的周期
|
||||
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.onBar(bar)
|
||||
return
|
||||
@ -265,9 +265,15 @@ class CtaLineBar(object):
|
||||
lastBar.low = min(lastBar.low, bar.low)
|
||||
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):
|
||||
"""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.__recountMa()
|
||||
self.__recountEma()
|
||||
@ -355,6 +361,10 @@ class CtaLineBar(object):
|
||||
self.bar.low = tick.lastPrice
|
||||
self.bar.close = tick.lastPrice
|
||||
|
||||
self.bar.mid4 = tick.lastPrice # 四价均价
|
||||
self.bar.mid5 = tick.lastPrice # 四价均价
|
||||
|
||||
|
||||
# K线的日期时间
|
||||
self.bar.date = tick.date # K线的日期时间(去除秒)设为第一个Tick的时间
|
||||
self.bar.time = tick.time # K线的日期时间(去除秒)设为第一个Tick的时间
|
||||
@ -379,7 +389,7 @@ class CtaLineBar(object):
|
||||
self.onBar(self.bar)
|
||||
return
|
||||
|
||||
# 清除8交易小时前的数据,
|
||||
# 清除480周期前的数据,
|
||||
if l1 > 60 * 8:
|
||||
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 ctaDemo import DoubleEmaDemo
|
||||
from strategy22_ArbitrageGrid import Strategy22
|
||||
from strategy24_M15RB import Strategy24
|
||||
|
||||
STRATEGY_CLASS = {}
|
||||
STRATEGY_CLASS['DataRecorder'] = DataRecorder
|
||||
STRATEGY_CLASS['DoubleEmaDemo'] = DoubleEmaDemo
|
||||
STRATEGY_CLASS['Strategy22'] = Strategy22
|
||||
STRATEGY_CLASS['Strategy24'] = Strategy24
|
@ -1027,6 +1027,7 @@ class TradingWidget(QtGui.QFrame):
|
||||
contract = self.mainEngine.getContract(symbol)
|
||||
|
||||
if contract:
|
||||
if not gatewayName:
|
||||
gatewayName = contract.gatewayName
|
||||
exchange = contract.exchange # 保证有交易所代码
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user