@Channelchan
2018-09-19T20:16:16.000000Z
字数 8339
阅读 1143
策略逻辑:设定唐安奇通道上线,为50分钟收盘最大值,当分钟的最大值突破上一分钟通道的上线1.01倍时认为有上涨趋势并做多,分钟最小值突破上线0.99倍且上一分钟是在上线之上时判断有下跌趋势并做空(若有仓位,突破时平仓,并且反向开仓)。
在一号的海龟策略基础上,增加了仓位管理操作,利用ATR判断波动率,波动率小的时候重仓,波动率大的时候弱仓。
# coding: utf-8
from vnpy.trader.vtConstant import *
from vnpy.trader.app.ctaStrategy.ctaTemplate import (CtaTemplate,
BarGenerator,
ArrayManager)
from collections import defaultdict
import numpy as np
import talib as ta
import pandas as pd
from datetime import datetime
class wangge_Strategy(CtaTemplate):
#单边海龟策略+波动率仓位管理
className = 'wangge_Strategy'
author = 'sky'
symbol = EMPTY_STRING
# 策略变量
posSize = 1 # 每笔下单的数量
fastWindow = 20 # 快速均线参数
slowWindow = 80 # 慢速均线参数
stopRatio = 0.06 # 止损比例
fixsize = 1
transactionPrice = EMPTY_FLOAT # 记录成交价格
wave = EMPTY_FLOAT
##########
# 参数列表,保存了参数的名称
paramList = ['name',
'className',
'author',
'symbol',
'fastWindow',
'slowWindow',
'stopRatio',
'profitMultiplier']
# 变量列表,保存了变量的名称
varList = ['inited',
'trading',
'posDict',
'transactionPrice',
'maTrend']
# 同步列表,保存了需要保存到数据库的变量名称
syncList = ['posDict',
'eveningDict',
'bondDict']
#----------------------------------------------------------------------
def __init__(self, ctaEngine, setting):
# 首先找到策略的父类(就是类CtaTemplate),然后把DoubleMaStrategy的对象转换为类CtaTemplate的对象
super(wangge_Strategy, self).__init__(ctaEngine, setting)
#----------------------------------------------------------------------
def onInit(self):
"""初始化策略(必须由用户继承实现)"""
self.writeCtaLog(u'海龟策略初始化')
# 初始化仓位字典
self.symbol = self.symbolList[0]
self.generateBarDict(self.onBar)
self.generateBarDict(self.onBar,5,self.on5MinBar,size =100)
if self.ctaEngine.engineType == 'trading':
# 实盘载入1分钟历史数据,并采用回放计算的方式初始化策略参数
# 通用可选参数:["1min","5min","15min","30min","60min","4hour","1day","1week","1month"]
pastbar1 = self.loadHistoryBar(self.Symbol,
type_ = "1min", size = 1000)
# 更新数据矩阵(optional)
for bar1 in zip (pastbar1):
self.amDict[self.symbol].updateBar(bar1)
elif self.ctaEngine.engineType == 'backtesting':
# 获取回测设置中的initHours长度的历史数据
self.initBacktesingData()
self.putEvent()
#----------------------------------------------------------------------
def onStart(self):
"""启动策略(必须由用户继承实现)"""
self.writeCtaLog(u'网格策略初始化')
#print('start',file=test)
self.putEvent()
#----------------------------------------------------------------------
def onStop(self):
"""停止策略(必须由用户继承实现)"""
self.putEvent()
#----------------------------------------------------------------------
def onTick(self, tick):
"""收到行情TICK推送(必须由用户继承实现)"""
pass
def onBar(self, bar):
"""收到Bar推送(必须由用户继承实现)"""
self.writeCtaLog('stg_onbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,bar.close))
self.bg5Dict[bar.vtSymbol].updateBar(bar)
am = self.am5Dict[self.symbol]
# fastMa = ta.MA(am.close, self.fastWindow)
# slowMa = ta.MA(am.close, self.slowWindow)
# if fastMa[-2] < slowMa[-2] and fastMa[-1] > slowMa[-1]:
# self.Trend = 1
# else:
# self.Trend = 0
# if slowMa[-1]>slowMa[-2]:
# self.wave = 1
# else:
# self.wave = 0
# if (self.posDict[self.symbol+"_LONG"] >0 and self.posDict[self.symbol+"_LONG"] <10):
# if self.wave == 0:
# self.sell(self.symbol, bar.close*0.98, self.posDict[self.symbol+"_LONG"], priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
# n = int((bar.close-self.transactionPrice)/0.001)
# print('n:%s,bar.close:%s,self.transactionPrice:%s'%(n,bar.close,self.transactionPrice))
# if n>0:
# self.sell(self.symbol, bar.close, n,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
# if self.posDict[self.symbol+"_LONG"] == 0:
# if self.wave == 1:
# self.buy(self.symbol, bar.close*0.98, 5, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
# elif n<0:
# self.buy(self.symbol, bar.close*0.98, -n, priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
if self.posDict[self.symbol+"_LONG"] ==5:
self.sell(self.symbol, bar.close, 5,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
def on5MinBar(self, bar):
"""15分钟K线推送"""
self.writeCtaLog('stg_on5Minbar_check_%s_%s_%s'%(bar.vtSymbol,bar.datetime,self.am5Dict[bar.vtSymbol].close))
self.am5Dict[bar.vtSymbol].updateBar(bar)
am5 = self.am5Dict[self.symbol]
fastMa = ta.MA(am5.close, self.fastWindow)
slowMa = ta.MA(am5.close, self.slowWindow)
if fastMa[-2] < fastMa[-1] and slowMa[-2] > slowMa[-1]:
self.Trend = 1
else:
self.Trend = 0
if (self.posDict[self.symbol+"_LONG"] == 0) and (self.posDict[self.symbol+"_SHORT"] == 0):
if self.Trend == 1:
self.buy(self.symbol, bar.close*1.02 , 5 ,priceType = PRICETYPE_LIMITPRICE,levelRate = 10)
######### 计算策略需要的信号-------------------------------------------------####################################
self.putEvent()
def onOrder(self, order):
"""收到委托变化推送(必须由用户继承实现)"""
# 对于无需做细粒度委托控制的策略,可以忽略onOrder
pass
#----------------------------------------------------------------------
def onTrade(self, trade):
"""收到成交推送(必须由用户继承实现)"""
self.transactionPrice = trade.price
#print('price:%s, direction:%s,offset:%s,self.Cross:%s,tradeVolume: %s'
#%(trade.price, trade.direction, trade.offset,self.Cross,trade.volume),file=test0)
pass
#----------------------------------------------------------------------
def onStopOrder(self, so):
"""停止单推送"""
pass
from __future__ import division
from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine
from vnpy.trader.app.ctaStrategy.ctaBase import *
if __name__ == '__main__':
# 创建回测引擎
engine = BacktestingEngine()
# 设置引擎的回测模式为K线
engine.setBacktestingMode(engine.BAR_MODE)
# 设置回测用的数据起始日期
engine.setStartDate('20180820 01:01',initHours=1) # 设置回测用的数据起始日期
engine.setEndDate('20180823 16:01')
# 设置产品相关参数
engine.setSlippage(0.2) # 股指1跳
engine.setRate(0.3/10000) # 万0.3
engine.setSize(300) # 股指合约大小
engine.setPriceTick(0.2) # 股指最小价格变动
# 设置使用的历史数据库
engine.setDatabase('OANDA_M1')
# 在引擎中创建策略对象
d = {'symbolList':['AUD_USD:oanda']}
engine.initStrategy(wangge_Strategy, d)
# 开始跑回测
engine.runBacktesting()
# 输出策略的回测日志
import pandas as pd
from datetime import datetime
import os
log = engine.logList
dataframe = pd.DataFrame(log)
filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'
filename = os.path.abspath(filename)
dataframe.to_csv(filename,index=False,sep=',')
# 显示回测结果
engine.showBacktestingResult()
engine.showDailyResult()
仓位字典构造完成
初始仓位: {'AUD_USD:oanda_LONG': 0, 'AUD_USD:oanda_SHORT': 0}
可平仓量: {'AUD_USD:oanda_LONG': 0, 'AUD_USD:oanda_SHORT': 0}
2018-09-18 23:42:54.797719 开始回测
2018-09-18 23:42:54.797719 策略初始化
2018-09-18 23:42:54.798719 载入历史数据。数据范围:[20180820 00:01,20180820 01:01)
2018-09-18 23:42:54.820751 We don't have AUD_USD:oanda in database
2018-09-18 23:42:54.821751 Our database have these symbols: []
2018-09-18 23:42:54.821751 !!没有数据 没有数据 没有数据!!
2018-09-18 23:42:54.821751 策略初始化完成
2018-09-18 23:42:54.821751 策略启动完成
2018-09-18 23:42:54.821751 开始回放回测数据,回测范围:[20180820 01:01,20180823 16:01)
2018-09-18 23:42:54.822750 载入历史数据。数据范围:[20180820 01:01,20180823 16:01)
2018-09-18 23:42:54.829745 We don't have AUD_USD:oanda in database
2018-09-18 23:42:54.829745 Our database have these symbols: []
2018-09-18 23:42:54.829745 !!没有数据 没有数据 没有数据!!
2018-09-18 23:42:54.829745 数据回放结束
2018-09-18 23:42:54.839739 计算回测结果
2018-09-18 23:42:54.840746 成交记录为空,无法计算回测结果
2018-09-18 23:42:54.840746 ------------------------------
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-2-ba112c76f517> in <module>()
37 dataframe.to_csv(filename,index=False,sep=',')
38 # 显示回测结果
---> 39 engine.showBacktestingResult()
40 engine.showDailyResult()
C:\ProgramData\Anaconda3\lib\site-packages\vnpy_fxdayu-1.1.0-py3.6.egg\vnpy\trader\app\ctaStrategy\ctaBacktesting.py in showBacktestingResult(self)
990 # 输出
991 self.output('-' * 30)
--> 992 self.output(u'第一笔交易:\t%s' % d['timeList'][0])
993 self.output(u'最后一笔交易:\t%s' % d['timeList'][-1])
994
KeyError: 'timeList'
def test(symboll):
from vnpy.trader.app.ctaStrategy.ctaBacktesting import BacktestingEngine, OptimizationSetting, MINUTE_DB_NAME
# 创建回测引擎对象
engine = BacktestingEngine()
# 设置回测使用的数据
engine.setBacktestingMode(engine.BAR_MODE) # 设置引擎的回测模式为K线
engine.setDatabase(MINUTE_DB_NAME) # 设置使用的历史数据库
engine.setStartDate('2018001 01:01',initHours=1) # 设置回测用的数据起始日期
engine.setEndDate('20180905 16:01')
# 配置回测引擎参数
engine.setSlippage(0.2) # 设置滑点为股指1跳
engine.setRate(0.3/10000) # 设置手续费万0.3
engine.setSize(300) # 设置股指合约大小
engine.setPriceTick(0.2) # 设置股指最小价格变动
engine.setCapital(1000000) # 设置回测本金
# # 在引擎中创建策略对象
d = {'symbolList':[symboll]} # 策略参数配置
engine.initStrategy(DeStrategy, d) # 创建策略对象
engine.runBacktesting()
import pandas as pd
from datetime import datetime
import os
log = engine.logList
dataframe = pd.DataFrame(log)
filename = 'BTG_' + datetime.now().strftime("%Y%m%d_%H%M%S") +'.csv'
filename = os.path.abspath(filename)
dataframe.to_csv(filename,index=False,sep=',')
# 显示回测结果
# 显示逐日回测结果
engine.showDailyResult()
# 显示逐笔回测结果
engine.showBacktestingResult()
test('EOSUSDT:binance')
symbol = ['EOSUSDT:binance','BTCUSDT:binance','ETCUSDT:binance','ETHUSDT:binance','LTCUSDT:binance']
for i in symbol:
test(i)
# # 显示前10条成交记录
# for i in range(1000):
# d = engine.tradeDict[str(i+1)].__dict__
# print('TradeID: %s, Time: %s, Direction: %s, Price: %s, Volume: %s' %(d['tradeID'], d['dt'], d['direction'], d['price'], d['volume']))