vnpy/vn.trader/ctaStrategy/ctaPosition.py
2017-04-30 22:21:14 +08:00

151 lines
5.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# encoding: UTF-8
from vtConstant import *
from ctaBase import *
import talib as ta
from datetime import datetime
DEBUGCTALOG = True
class CtaPosition:
"""策略的仓位管理类
v 0.1 简单的数值,代表多仓数量和空仓数量
v 0.2 增加多仓和空仓的持仓,去除持仓均价
"""
def __init__(self, strategy):
self.strategy = strategy
self.longPos = 0 # 多仓持仓
self.shortPos = 0 # 空仓持仓
self.pos = 0 # 持仓状态 0:空仓/对空平等; >=1 净多仓 <=-1 净空仓
self.maxPos = 1 # 最大持仓量(多仓+空仓总量)
self.step = 1 # 增仓数量
# disabled in v0.2
#self.posList = []
#self.avgPrice = EMPTY_FLOAT
def avaliablePos2Add(self):
"""剩余可加的仓位数量"""
return self.maxPos - abs(self.longPos) - abs(self.shortPos)
def openPos(self, direction, vol, price=EMPTY_FLOAT):
"""开、加仓"""
# vol: 正整数
# disabled in v0.2
#if self.pos == 0:
# self.posList = []
if direction == DIRECTION_LONG: # 加多仓
if (max(self.pos, self.longPos) + vol) > self.maxPos:
self.writeCtaError(u'异常,超出仓位。净:{0},多:{1},加多:{2},最大:{3}'
.format(self.pos, self.longPos, vol, self.maxPos))
# 只告警
#return False
# 更新
self.writeCtaLog(u'多仓:{0}->{1}'.format(self.longPos, self.longPos + vol))
self.writeCtaLog(u'净:{0}->{1}'.format(self.pos, self.pos + vol))
self.longPos += vol
self.pos += vol
# 更新上层策略的pos。该方法不推荐使用
self.strategy.pos = self.pos
if direction == DIRECTION_SHORT: # 加空仓
if (min(self.pos, self.shortPos) - vol) < (0 - self.maxPos):
self.writeCtaError(u'异常,超出仓位。净:{0},空:{1},加空:{2},最大:{3}'
.format(self.pos, self.shortPos, vol, self.maxPos))
#return False
self.writeCtaLog(u'空仓:{0}->{1}'.format(self.shortPos, self.shortPos - vol))
self.writeCtaLog(u'净:{0}->{1}'.format(self.pos, self.pos-vol))
self.shortPos -= vol
self.pos -= vol
# 更新上层策略的pos。该方法不推荐使用
self.strategy.pos = self.pos
# v0.2 disabled
#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):
"""平、减仓"""
# vol: 正整数
if direction == DIRECTION_LONG: # 平空仓 Cover
if self.shortPos + vol > 0:
self.writeCtaError(u'异常,超出仓位。净:{0},空:{1},平仓:{2}'.format(self.pos, self.shortPos, vol))
#self.strategy.pos = self.pos
#return False
self.writeCtaLog(u'空仓:{0}->{1}'.format(self.shortPos, self.shortPos + vol))
self.writeCtaLog(u'净:{0}->{1}'.format(self.pos, self.pos + vol))
self.shortPos += vol
self.pos += vol
# 更新上层策略的pos。该方法不推荐使用
self.strategy.pos = self.pos
if direction == DIRECTION_SHORT: # 平多仓
if self.longPos - vol < 0:
self.writeCtaError(u'异常,超出仓位。净:{0},多:{1},平仓:{2}'.format(self.pos, self.longPos, vol))
#self.strategy.pos = self.pos
#return False
self.writeCtaLog(u'多仓:{0}->{1}'.format(self.longPos, self.longPos - vol))
self.writeCtaLog(u'净:{0}->{1}'.format(self.pos, self.pos-vol))
self.shortPos -= vol
self.pos -= vol
self.strategy.pos = self.pos
# disabled in v0.2
#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 clear(self):
"""清除状态"""
self.writeCtaLog(u'清除所有持仓状态')
self.pos = 0
self.longPos = 0
self.shortPos = 0
# 更新上层策略的pos
self.strategy.pos = 0
# ----------------------------------------------------------------------
def writeCtaError(self, content):
"""记录CTA日志错误"""
self.strategy.writeCtaLog(content)
# ----------------------------------------------------------------------
def writeCtaLog(self, content):
"""记录CTA日志"""
self.strategy.writeCtaLog(content)
def debugCtaLog(self, content):
"""记录CTA日志"""
if DEBUGCTALOG:
self.strategy.writeCtaLog('[DEBUG]'+content)