[Mod]修改CTA自带策略使用ArrayManager,技术指标函数支持返回数组
This commit is contained in:
parent
b901e579ae
commit
ce65a32159
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -2,7 +2,7 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -16,7 +16,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -28,7 +28,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
@ -42,7 +42,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -58,7 +58,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": true
|
||||
},
|
||||
@ -71,25 +71,11 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"collapsed": false
|
||||
},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2017-10-07 18:16:51.192000\t开始载入数据\n",
|
||||
"2017-10-07 18:16:51.306000\t载入完成,数据量:332899\n",
|
||||
"2017-10-07 18:16:51.306000\t开始回测\n",
|
||||
"2017-10-07 18:16:51.306000\t策略初始化完成\n",
|
||||
"2017-10-07 18:16:51.306000\t策略启动完成\n",
|
||||
"2017-10-07 18:16:51.306000\t开始回放数据\n",
|
||||
"2017-10-07 18:17:04.696000\t数据回放结束\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# 运行回测\n",
|
||||
"engine.runBacktesting()"
|
||||
|
@ -486,34 +486,73 @@ class ArrayManager(object):
|
||||
return self.volumeArray
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def sma(self, n, shift=0):
|
||||
"""均线"""
|
||||
return talib.SMA(self.close, n)[-1-shift]
|
||||
|
||||
def sma(self, n, array=False):
|
||||
"""简单均线"""
|
||||
result = talib.SMA(self.close, n)
|
||||
if array:
|
||||
return result
|
||||
return result[-1]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def std(self, n, shift=0):
|
||||
def std(self, n, array=False):
|
||||
"""标准差"""
|
||||
return talib.STDDEV(self.close, n)[-1-shift]
|
||||
result = talib.STDDEV(self.close, n)
|
||||
if array:
|
||||
return result
|
||||
return result[-1]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def boll(self, n, dev, shift=0):
|
||||
def cci(self, n, array=False):
|
||||
"""CCI指标"""
|
||||
result = talib.CCI(self.high, self.low, self.close, n)
|
||||
if array:
|
||||
return result
|
||||
return result[-1]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def atr(self, n, array=False):
|
||||
"""ATR指标"""
|
||||
result = talib.ATR(self.high, self.low, self.close, n)
|
||||
if array:
|
||||
return result
|
||||
return result[-1]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def rsi(self, n, array=False):
|
||||
"""RSI指标"""
|
||||
result = talib.RSI(self.close, n)
|
||||
if array:
|
||||
return result
|
||||
return result[-1]
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def boll(self, n, dev, array=False):
|
||||
"""布林通道"""
|
||||
mid = self.sma(n, shift)
|
||||
std = self.std(n, shift)
|
||||
mid = self.sma(n, array)
|
||||
std = self.std(n, array)
|
||||
|
||||
up = mid + std * dev
|
||||
down = mid - std * dev
|
||||
|
||||
return up, down
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def keltner(self, n, dev, array=False):
|
||||
"""肯特纳通道"""
|
||||
mid = self.sma(n, array)
|
||||
atr = self.atr(n, array)
|
||||
|
||||
up = mid + atr * dev
|
||||
down = mid - atr * dev
|
||||
|
||||
return up, down
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def cci(self, n, shift=0):
|
||||
"""CCI指标"""
|
||||
return talib.CCI(self.high, self.low, self.close, n)[-1-shift]
|
||||
def donchian(self, n, array=False):
|
||||
"""唐奇安通道"""
|
||||
up = talib.MAX(self.high, n)
|
||||
down = talib.MIN(self.low, n)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def atr(self, n, shift=0):
|
||||
"""ATR指标"""
|
||||
return talib.ATR(self.high, self.low, self.close, n)[-1-shift]
|
||||
|
||||
|
||||
if array:
|
||||
return up, down
|
||||
return up[-1], down[-1]
|
@ -10,12 +10,11 @@
|
||||
|
||||
"""
|
||||
|
||||
import talib
|
||||
import numpy as np
|
||||
|
||||
from vnpy.trader.vtObject import VtBarData
|
||||
from vnpy.trader.vtConstant import EMPTY_STRING
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import CtaTemplate, BarManager
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
|
||||
BarManager,
|
||||
ArrayManager)
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -34,17 +33,8 @@ class AtrRsiStrategy(CtaTemplate):
|
||||
fixedSize = 1 # 每次交易的数量
|
||||
|
||||
# 策略变量
|
||||
bufferSize = 100 # 需要缓存的数据的大小
|
||||
bufferCount = 0 # 目前已经缓存了的数据的计数
|
||||
highArray = np.zeros(bufferSize) # K线最高价的数组
|
||||
lowArray = np.zeros(bufferSize) # K线最低价的数组
|
||||
closeArray = np.zeros(bufferSize) # K线收盘价的数组
|
||||
|
||||
atrCount = 0 # 目前已经缓存了的ATR的计数
|
||||
atrArray = np.zeros(bufferSize) # ATR指标的数组
|
||||
atrValue = 0 # 最新的ATR指标数值
|
||||
atrMa = 0 # ATR移动平均的数值
|
||||
|
||||
rsiValue = 0 # RSI指标的数值
|
||||
rsiBuy = 0 # RSI买开阈值
|
||||
rsiSell = 0 # RSI卖开阈值
|
||||
@ -81,6 +71,7 @@ class AtrRsiStrategy(CtaTemplate):
|
||||
|
||||
# 创建K线合成器对象
|
||||
self.bm = BarManager(self.onBar)
|
||||
self.am = ArrayManager()
|
||||
|
||||
# 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
|
||||
# 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
|
||||
@ -129,34 +120,17 @@ class AtrRsiStrategy(CtaTemplate):
|
||||
self.orderList = []
|
||||
|
||||
# 保存K线数据
|
||||
self.closeArray[0:self.bufferSize-1] = self.closeArray[1:self.bufferSize]
|
||||
self.highArray[0:self.bufferSize-1] = self.highArray[1:self.bufferSize]
|
||||
self.lowArray[0:self.bufferSize-1] = self.lowArray[1:self.bufferSize]
|
||||
|
||||
self.closeArray[-1] = bar.close
|
||||
self.highArray[-1] = bar.high
|
||||
self.lowArray[-1] = bar.low
|
||||
|
||||
self.bufferCount += 1
|
||||
if self.bufferCount < self.bufferSize:
|
||||
am = self.am
|
||||
am.updateBar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
|
||||
# 计算指标数值
|
||||
self.atrValue = talib.ATR(self.highArray,
|
||||
self.lowArray,
|
||||
self.closeArray,
|
||||
self.atrLength)[-1]
|
||||
self.atrArray[0:self.bufferSize-1] = self.atrArray[1:self.bufferSize]
|
||||
self.atrArray[-1] = self.atrValue
|
||||
|
||||
self.atrCount += 1
|
||||
if self.atrCount < self.bufferSize:
|
||||
return
|
||||
|
||||
self.atrMa = talib.MA(self.atrArray,
|
||||
self.atrMaLength)[-1]
|
||||
self.rsiValue = talib.RSI(self.closeArray,
|
||||
self.rsiLength)[-1]
|
||||
atrArray = am.atr(self.atrLength, array=True)
|
||||
self.atrValue = atrArray[-1]
|
||||
self.atrMa = atrArray[-self.atrMaLength:].mean()
|
||||
|
||||
self.rsiValue = am.rsi(self.rsiLength)
|
||||
|
||||
# 判断是否要进行交易
|
||||
|
||||
|
@ -18,9 +18,6 @@
|
||||
|
||||
from __future__ import division
|
||||
|
||||
import talib
|
||||
import numpy as np
|
||||
|
||||
from vnpy.trader.vtObject import VtBarData
|
||||
from vnpy.trader.vtConstant import EMPTY_STRING
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
|
||||
|
@ -1,7 +1,7 @@
|
||||
# encoding: UTF-8
|
||||
|
||||
"""
|
||||
这里的Demo是一个最简单的策略实现,并未考虑太多实盘中的交易细节,如:
|
||||
这里的Demo是一个最简单的双均线策略实现,并未考虑太多实盘中的交易细节,如:
|
||||
1. 委托价格超出涨跌停价导致的委托失败
|
||||
2. 委托未成交,需要撤单后重新委托
|
||||
3. 断网后恢复交易状态
|
||||
@ -13,28 +13,28 @@
|
||||
|
||||
from __future__ import division
|
||||
|
||||
from vnpy.trader.vtObject import VtBarData
|
||||
#from vnpy.trader.vtObject import VtBarData
|
||||
from vnpy.trader.vtConstant import EMPTY_STRING, EMPTY_FLOAT
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import CtaTemplate, BarManager
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
|
||||
BarManager,
|
||||
ArrayManager)
|
||||
|
||||
|
||||
########################################################################
|
||||
class EmaDemoStrategy(CtaTemplate):
|
||||
class DoubleMaStrategy(CtaTemplate):
|
||||
"""双指数均线策略Demo"""
|
||||
className = 'EmaDemoStrategy'
|
||||
className = 'DoubleMaStrategy'
|
||||
author = u'用Python的交易员'
|
||||
|
||||
# 策略参数
|
||||
fastK = 0.9 # 快速EMA参数
|
||||
slowK = 0.1 # 慢速EMA参数
|
||||
fastWindow = 10 # 快速均线参数
|
||||
slowWindow = 60 # 慢速均线参数
|
||||
initDays = 10 # 初始化数据所用的天数
|
||||
|
||||
# 策略变量
|
||||
fastMa = [] # 快速EMA均线数组
|
||||
fastMa0 = EMPTY_FLOAT # 当前最新的快速EMA
|
||||
fastMa1 = EMPTY_FLOAT # 上一根的快速EMA
|
||||
|
||||
slowMa = [] # 与上面相同
|
||||
|
||||
slowMa0 = EMPTY_FLOAT
|
||||
slowMa1 = EMPTY_FLOAT
|
||||
|
||||
@ -43,8 +43,8 @@ class EmaDemoStrategy(CtaTemplate):
|
||||
'className',
|
||||
'author',
|
||||
'vtSymbol',
|
||||
'fastK',
|
||||
'slowK']
|
||||
'fastWindow',
|
||||
'slowWindow']
|
||||
|
||||
# 变量列表,保存了变量的名称
|
||||
varList = ['inited',
|
||||
@ -58,16 +58,15 @@ class EmaDemoStrategy(CtaTemplate):
|
||||
#----------------------------------------------------------------------
|
||||
def __init__(self, ctaEngine, setting):
|
||||
"""Constructor"""
|
||||
super(EmaDemoStrategy, self).__init__(ctaEngine, setting)
|
||||
super(DoubleMaStrategy, self).__init__(ctaEngine, setting)
|
||||
|
||||
self.bm = BarManager(self.onBar)
|
||||
self.am = ArrayManager()
|
||||
|
||||
# 注意策略类中的可变对象属性(通常是list和dict等),在策略初始化时需要重新创建,
|
||||
# 否则会出现多个策略实例之间数据共享的情况,有可能导致潜在的策略逻辑错误风险,
|
||||
# 策略类中的这些可变对象属性可以选择不写,全都放在__init__下面,写主要是为了阅读
|
||||
# 策略时方便(更多是个编程习惯的选择)
|
||||
self.fastMa = []
|
||||
self.slowMa = []
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onInit(self):
|
||||
@ -100,23 +99,20 @@ class EmaDemoStrategy(CtaTemplate):
|
||||
#----------------------------------------------------------------------
|
||||
def onBar(self, bar):
|
||||
"""收到Bar推送(必须由用户继承实现)"""
|
||||
am = self.am
|
||||
am.updateBar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
|
||||
# 计算快慢均线
|
||||
if not self.fastMa0:
|
||||
self.fastMa0 = bar.close
|
||||
self.fastMa.append(self.fastMa0)
|
||||
else:
|
||||
self.fastMa1 = self.fastMa0
|
||||
self.fastMa0 = bar.close * self.fastK + self.fastMa0 * (1 - self.fastK)
|
||||
self.fastMa.append(self.fastMa0)
|
||||
|
||||
if not self.slowMa0:
|
||||
self.slowMa0 = bar.close
|
||||
self.slowMa.append(self.slowMa0)
|
||||
else:
|
||||
self.slowMa1 = self.slowMa0
|
||||
self.slowMa0 = bar.close * self.slowK + self.slowMa0 * (1 - self.slowK)
|
||||
self.slowMa.append(self.slowMa0)
|
||||
|
||||
fastMa = am.sma(self.fastWindow, array=True)
|
||||
self.fastMa0 = fastMa[-1]
|
||||
self.fastMa1 = fastMa[-2]
|
||||
|
||||
slowMa = am.sma(self.slowWindow, array=True)
|
||||
self.slowMa0 = slowMa[-1]
|
||||
self.slowMa1 = slowMa[-2]
|
||||
|
||||
# 判断买卖
|
||||
crossOver = self.fastMa0>self.slowMa0 and self.fastMa1<self.slowMa1 # 金叉上穿
|
||||
crossBelow = self.fastMa0<self.slowMa0 and self.fastMa1>self.slowMa1 # 死叉下穿
|
@ -12,12 +12,11 @@
|
||||
|
||||
from __future__ import division
|
||||
|
||||
import talib
|
||||
import numpy as np
|
||||
|
||||
from vnpy.trader.vtObject import VtBarData
|
||||
from vnpy.trader.vtConstant import EMPTY_STRING
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import CtaTemplate, BarManager
|
||||
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
|
||||
BarManager,
|
||||
ArrayManager)
|
||||
|
||||
|
||||
########################################################################
|
||||
@ -34,14 +33,6 @@ class KkStrategy(CtaTemplate):
|
||||
fixedSize = 1 # 每次交易的数量
|
||||
|
||||
# 策略变量
|
||||
bufferSize = 100 # 需要缓存的数据的大小
|
||||
bufferCount = 0 # 目前已经缓存了的数据的计数
|
||||
highArray = np.zeros(bufferSize) # K线最高价的数组
|
||||
lowArray = np.zeros(bufferSize) # K线最低价的数组
|
||||
closeArray = np.zeros(bufferSize) # K线收盘价的数组
|
||||
|
||||
atrValue = 0 # 最新的ATR指标数值
|
||||
kkMid = 0 # KK通道中轨
|
||||
kkUp = 0 # KK通道上轨
|
||||
kkDown = 0 # KK通道下轨
|
||||
intraTradeHigh = 0 # 持仓期内的最高点
|
||||
@ -63,8 +54,6 @@ class KkStrategy(CtaTemplate):
|
||||
varList = ['inited',
|
||||
'trading',
|
||||
'pos',
|
||||
'atrValue',
|
||||
'kkMid',
|
||||
'kkUp',
|
||||
'kkDown']
|
||||
|
||||
@ -74,6 +63,7 @@ class KkStrategy(CtaTemplate):
|
||||
super(KkStrategy, self).__init__(ctaEngine, setting)
|
||||
|
||||
self.bm = BarManager(self.onBar, 5, self.onFiveBar) # 创建K线合成器对象
|
||||
self.am = ArrayManager()
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
def onInit(self):
|
||||
@ -118,27 +108,14 @@ class KkStrategy(CtaTemplate):
|
||||
self.orderList = []
|
||||
|
||||
# 保存K线数据
|
||||
self.closeArray[0:self.bufferSize-1] = self.closeArray[1:self.bufferSize]
|
||||
self.highArray[0:self.bufferSize-1] = self.highArray[1:self.bufferSize]
|
||||
self.lowArray[0:self.bufferSize-1] = self.lowArray[1:self.bufferSize]
|
||||
|
||||
self.closeArray[-1] = bar.close
|
||||
self.highArray[-1] = bar.high
|
||||
self.lowArray[-1] = bar.low
|
||||
|
||||
self.bufferCount += 1
|
||||
if self.bufferCount < self.bufferSize:
|
||||
am = self.am
|
||||
am.updateBar(bar)
|
||||
if not am.inited:
|
||||
return
|
||||
|
||||
|
||||
# 计算指标数值
|
||||
self.atrValue = talib.ATR(self.highArray,
|
||||
self.lowArray,
|
||||
self.closeArray,
|
||||
self.kkLength)[-1]
|
||||
self.kkMid = talib.MA(self.closeArray, self.kkLength)[-1]
|
||||
self.kkUp = self.kkMid + self.atrValue * self.kkDev
|
||||
self.kkDown = self.kkMid - self.atrValue * self.kkDev
|
||||
|
||||
self.kkUp, self.kkDown = am.keltner(self.kkLength, self.kkDev)
|
||||
|
||||
# 判断是否要进行交易
|
||||
|
||||
# 当前无仓位,发送OCO开仓委托
|
||||
|
Loading…
Reference in New Issue
Block a user