From f6a26237200a1cd31e5ea08fcd5d9afc77f0bb1a Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Wed, 17 Jan 2018 10:48:13 +0800 Subject: [PATCH 1/5] =?UTF-8?q?[Fix]=E4=BF=AE=E5=A4=8D=E6=8C=81=E4=BB=93?= =?UTF-8?q?=E4=BB=B7=E6=A0=BC=E8=AE=A1=E7=AE=97=E5=8F=AF=E8=83=BD=E5=87=BA?= =?UTF-8?q?=E9=94=99=E7=9A=84bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vnpy/trader/vtEngine.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/vnpy/trader/vtEngine.py b/vnpy/trader/vtEngine.py index b3c0482e..41430b44 100644 --- a/vnpy/trader/vtEngine.py +++ b/vnpy/trader/vtEngine.py @@ -819,12 +819,18 @@ class PositionDetail(object): cost = self.longPrice * self.longPos cost += trade.volume * trade.price newPos = self.longPos + trade.volume - self.longPrice = cost / newPos + if newPos: + self.longPrice = cost / newPos + else: + self.longPrice = 0 else: cost = self.shortPrice * self.shortPos cost += trade.volume * trade.price newPos = self.shortPos + trade.volume - self.shortPrice = cost / newPos + if newPos: + self.shortPrice = cost / newPos + else: + self.shortPrice = 0 #---------------------------------------------------------------------- def calculatePosition(self): From 83ff2beac1f06bb5803bedf3a9e67a92e21be448 Mon Sep 17 00:00:00 2001 From: Felix Yan Date: Thu, 18 Jan 2018 12:55:58 +0800 Subject: [PATCH 2/5] Fix a typo in README-en.md --- README-en.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README-en.md b/README-en.md index a808f598..fdd3993f 100644 --- a/README-en.md +++ b/README-en.md @@ -63,7 +63,7 @@ Using the vn.py project, institutional investors and professional traders, such 3. RPC framework (vn.rpc) which also supports pushing data from server to client, aimed at implementing distributed trading systems. -4. Ready to use trading platform (vn.trader), which has intergrated all the trading APIs in vn.api, and provides easy to use strategy engines for developing different types of quantitative strategies and trading algorithms. +4. Ready to use trading platform (vn.trader), which has integrated all the trading APIs in vn.api, and provides easy to use strategy engines for developing different types of quantitative strategies and trading algorithms. 5. Tutorials about how to use vn.py to solve real world trading issues. From bd26888bcd5bee3f69051e7de9b58bf31a6453b8 Mon Sep 17 00:00:00 2001 From: yuanhuei <35559668+yuanhuei@users.noreply.github.com> Date: Thu, 18 Jan 2018 19:28:05 +0800 Subject: [PATCH 3/5] Update dataService.py MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 改变插入数据库中分钟k线时间戳,从分钟结束点改为分钟起始点,和vnpy程序内部以及策略处理一致。 --- examples/QuantosDataService/dataService.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/examples/QuantosDataService/dataService.py b/examples/QuantosDataService/dataService.py index 470a3e16..4246f6d8 100644 --- a/examples/QuantosDataService/dataService.py +++ b/examples/QuantosDataService/dataService.py @@ -27,6 +27,8 @@ config = open('config.json') setting = json.load(config) config.close() + + MONGO_HOST = setting['MONGO_HOST'] MONGO_PORT = setting['MONGO_PORT'] SYMBOLS = setting['SYMBOLS'] @@ -57,6 +59,18 @@ def generateVtBar(row): bar.date = str(row['trade_date']) bar.time = str(row['time']).rjust(6, '0') + + #将bar的时间改成提前一分钟 + hour=bar.time[0:2] + minute=bar.time[2:4] + sec=bar.time[4:6] + if minute=="00": + minute="59" + hour=str(int(hour)-1).rjust(2,'0') + else: + minute=str(int(minute)-1).rjust(2,'0') + bar.time=hour+minute+sec + bar.datetime = datetime.strptime(' '.join([bar.date, bar.time]), '%Y%m%d %H%M%S') return bar From 4ad43982ff7e6d55ebda33213b5e40db1f2988ae Mon Sep 17 00:00:00 2001 From: yuanhuei <35559668+yuanhuei@users.noreply.github.com> Date: Thu, 18 Jan 2018 19:40:52 +0800 Subject: [PATCH 4/5] Add files via upload --- examples/VnTrader/MystrategyBollingerBot.py | 362 ++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 examples/VnTrader/MystrategyBollingerBot.py diff --git a/examples/VnTrader/MystrategyBollingerBot.py b/examples/VnTrader/MystrategyBollingerBot.py new file mode 100644 index 00000000..d1afb40f --- /dev/null +++ b/examples/VnTrader/MystrategyBollingerBot.py @@ -0,0 +1,362 @@ +# encoding: UTF-8 + +""" +仅在知乎Live中分享,请勿外传。 + +基于布林通道通道的交易策略,适合用在股指上5分钟线上。 +""" + +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, BarGenerator, ArrayManager + +import csv +from vnpy.trader.vtConstant import (EMPTY_STRING, EMPTY_UNICODE, + EMPTY_FLOAT, EMPTY_INT) + +from vnpy.event import Event +from vnpy.trader.vtGlobal import globalSetting +from vnpy.trader.vtEvent import * +from vnpy.trader.vtGateway import * +from vnpy.trader.language import text +from vnpy.trader.vtFunction import getTempPath +######################################################################## +class MyBollingerBotStrategy(CtaTemplate): + """基于布林通道的交易策略""" + className = 'MyBollingerBotStrategy' + author = 'yuanhui' + + # 策略参数 + bollWindow = 26 # 通道窗口数 + entryDev = 2 # 开仓偏差 + exitDev = 1.2 # 平仓偏差 + trailingPrcnt = 0.4 # 移动止损百分比 + maWindow = 10 # 过滤用均线窗口 + initDays = 10 # 初始化数据所用的天数 + fixedSize = 1 # 每次交易的数量 + priceTick = 0.2 # 价格最小变动 + + DayTrendStatus='duotou' #DuoTou, KongTou,Panzheng + OnehourTrendstatus='panzhen' + FifteenMinTrendStatus='panzhen' + FiveMinTrendStatus='panzhen' + + # 5Min策略变量 + bollMid = 0 # 布林带中轨 + BeforebollMid=0 #上一根K线的布林线中轨 + bollStd = 0 # 布林带宽度 + bollUp = 0 # 开仓上轨 + Beforebollup=0 #上一根K线的布林线上轨 + bollDown = 0 # 平仓下轨 + beforebooldown=0 #上一根K线的布林线下轨 + + # 15Min策略变量 + bollMid15 = 0 # 布林带中轨 + BeforebollMid15=0 #上一根K线的布林线中轨 + bollStd15 = 0 # 布林带宽度 + bollUp15 = 0 # 开仓上轨 + Beforebollup15=0 #上一根K线的布林线上轨 + bollDown15 = 0 # 平仓下轨 + beforebolldown15=0 #上一根K线的布林线下轨 + + maFilter = 0 # 均线过滤 + maFilter1 = 0 # 上一期均线 + + intraTradeHigh = 0 # 持仓期内的最高点 + longEntry = 0 # 多头开仓 + longExit = 0 # 多头平仓 + shortEntry=0 + shortExit=0 + + deal=0 + dealopen=0 + + + orderList = [] # 保存委托代码的列表 + + # 参数列表,保存了参数的名称 + paramList = ['name', + 'className', + 'author', + 'vtSymbol', + 'bollWindow', + 'entryDev', + 'exitDev', + 'trailingPrcnt', + 'maWindow', + 'initDays', + 'fixedSize', + 'DayTrendStatus'] + + # 变量列表,保存了变量的名称 + varList = ['inited', + 'trading', + 'pos', + 'bollUp', + 'bollDown', + 'bollUp15', + 'bollDown15', + 'FifteenMinTrendStatus', + 'FiveMinTrendStatus'] + + # 同步列表 + syncList = ['pos', + 'intraTradeHigh'] + + #---------------------------------------------------------------------- + def __init__(self, ctaEngine, setting): + """Constructor""" + super(MyBollingerBotStrategy, self).__init__(ctaEngine, setting) + + self.bm = BarGenerator(self.onBar, 5, self.onFiveBar) + self.am = ArrayManager() + + self.bm15 = BarGenerator(self.onBar, 15, self.on15MinBar) + self.am15 = ArrayManager() + with open("datasig.csv","wb+") as csvfile: + writer = csv.writer(csvfile) + writer.writerow(["datetime","open","close","high","low","openInterest","volume","deal","pDown","pUp","dealOpen"]) + with open("datasig15.csv","wb+") as csvfile: + writer = csv.writer(csvfile) + writer.writerow(["datetime","open","close","high","low","openInterest","volume","deal","pDown","pUp","dealOpen"]) + + #---------------------------------------------------------------------- + def onInit(self): + """初始化策略(必须由用户继承实现)""" + self.writeCtaLog(u'%s策略初始化' %self.name) + + # 载入历史数据,并采用回放计算的方式初始化策略数值 + initData = self.loadBar(self.initDays) + for bar in initData: + self.onBar(bar) + + self.putEvent() + + #---------------------------------------------------------------------- + def onStart(self): + """启动策略(必须由用户继承实现)""" + self.writeCtaLog(u'%s策略启动' %self.name) + self.putEvent() + + #---------------------------------------------------------------------- + def onStop(self): + """停止策略(必须由用户继承实现)""" + self.writeCtaLog(u'%s策略停止' %self.name) + self.putEvent() + + #---------------------------------------------------------------------- + def onTick(self, tick): + """收到行情TICK推送(必须由用户继承实现)""" + self.bm.updateTick(tick) + + #---------------------------------------------------------------------- + def onBar(self, bar): + """收到Bar推送(必须由用户继承实现)""" + #self.bm.updateBar(bar) + # 基于15分钟判断趋势过滤,因此先更新 + self.bm15.updateBar(bar) + + # 基于5分钟判断 + self.bm.updateBar(bar) + print u"策略:",self.__dict__["name"] + print u"时间:%s,1分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,日趋势%s"%(bar.time,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.DayTrendStatus) + + #---------------------------------------------------------------------- + def onFiveBar(self, bar): + """收到5分钟K线""" + #计算上一个k线的布林中轨,上轨,下轨 + self.BeforebollMid=self.am.sma(self.bollWindow) + self.Beforebollup,self.beforebooldown=self.am.boll(self.bollWindow,self.entryDev) + # 保存K线数据 + self.am.updateBar(bar) + if not self.am.inited: + return + + # 撤销之前发出的尚未成交的委托(包括限价单和停止单) + self.cancelAll() + orderList=[] + + # 计算指标数值 + self.bollMid = self.am.sma(self.bollWindow) + #self.bollStd = self.am.std(self.bollWindow) + self.bollUp,self.bollDown = self.am.boll(self.bollWindow,self.entryDev) + #self.boolDown = self.bollMid - self.bollStd * self.entryDev + + #maArray = self.am.sma(self.maWindow, True) + #self.maFilter = maArray[-1] + #self.maFilter1 = maArray[-2] + #判断当前5Min布林线趋势状态 + if bar.high > self.Beforebollup: + self.FiveMinTrendStatus='duotou' + elif bar.low < self.beforebooldown: + self.FiveMinTrendStatus='kongtou' + elif bar.low < self.BeforebollMid and self.FiveMinTrendStatus=='duotou': + self.FiveMinTrendStatus='panzhen' + elif bar.high > self.BeforebollMid and self.FiveMinTrendStatus=='kongtou': + self.FiveMinTrendStatus='panzhen' + + if self.DayTrendStatus=='kongtou' and bar.high > self.bollMid15 and self.FifteenMinTrendStatus == 'kongtou': + self.FifteenMinTrendStatus=='panzhen' + if self.DayTrendStatus=='duotou' and bar.low < self.bollMid15 and self.FifteenMinTrendStatus == 'duotou': + + self.FifteenMinTrendStatus=='panzhen' + # 判断是否要进行交易 + print u"5分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s"%(self.FiveMinTrendStatus,self.FifteenMinTrendStatus) + # 当前无仓位,发送OCO开仓委托 + if self.pos == 0: + #self.intraTradeHigh = bar.high + + if self.DayTrendStatus=='duotou' and (self.FifteenMinTrendStatus=='panzhen' or self.FifteenMinTrendStatus=='kongtou'): + orderList=self.buy(self.bollUp15+self.priceTick, self.fixedSize, True) + print u"委托多单,15分钟上轨开仓" + elif self.DayTrendStatus=='duotou' and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': + self.longEntry = bar.close + orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) + print u"委托多单,5分钟收盘价开仓" + elif self.DayTrendStatus=='duotou' and self.FifteenMinTrendStatus=='duotou' and (self.FiveMinTrendStatus=='panzhen' or self.FiveMinTrendStatus=='kongtou'): + self.longEntry=self.bollUp + orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) + print u"委托多单,5分钟上轨开仓" + elif self.DayTrendStatus=='kongtou' and (self.FifteenMinTrendStatus=='panzhen' or self.FifteenMinTrendStatus=='duotou') : + self.orderList=self.short(self.bollDown15-self.priceTick, self.fixedSize, True) + print u"委托空单,15分钟下轨开仓" + elif self.DayTrendStatus=='kongtou' and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': + self.shortEntry = bar.close + orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) + print u"委托空单,5分钟收盘价开仓" + elif self.DayTrendStatus=='kongtou' and self.FifteenMinTrendStatus=='kongtou' and (self.FiveMinTrendStatus=='panzhen' or self.FiveMinTrendStatus=='duotou'): + self.shortEntry=self.bollDown + orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) + print u"委托空单,5分钟下轨开仓" + + + # 持有多头仓位 + elif self.pos > 0: + #self.intraTradeHigh = max(self.intraTradeHigh, bar.high) + #self.longExit = self.intraTradeHigh * (1 - self.trailingPrcnt/100) + #self.longExit = min(self.longExit, self.exitUp) + #self.longExit=self.boolDown + + orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) + print u"委托止损单,5分钟下轨平仓" + # 持有空头仓位 + elif self.pos < 0: + orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) + print u"委托止损单,5分钟上轨平仓" + + with open("datasig.csv","ab+",) as csvfile: + writer = csv.writer(csvfile) + writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,0,0,self.dealopen]) + self.deal=0 + self.dealopen=0 + + + if orderList: + print u"委托单成功单号",orderList + else: + print u"委托单失败" + # 发出状态更新事件 + self.putEvent() + + + def on15MinBar(self, bar): + """15分钟K线推送""" + + #计算上一个k线的布林中轨,上轨,下轨 + self.BeforebollMid15=self.am15.sma(self.bollWindow) + self.Beforebollup15,self.beforebolldown15=self.am15.boll(self.bollWindow,self.entryDev) + + self.am15.updateBar(bar) + + if not self.am15.inited: + return + + # 计算指标数值 + self.bollMid15 = self.am.sma(self.bollWindow) + self.bollUp15,self.bollDown15 = self.am.boll(self.bollWindow,self.entryDev) + + + #判断当前15Min布林线趋势状态 + if bar.high > self.Beforebollup15 and bar.low > self.BeforebollMid15: + self.FifteenMinTrendStatus='duotou' + elif bar.low < self.beforebolldown15 and bar.high < self.Beforebollup15: + self.FifteenMinTrendStatus='kongtou' + elif bar.low < self.BeforebollMid15 and self.FifteenMinTrendStatus=='duotou': + self.FifteenMinTrendStatus='panzhen' + elif bar.high > self.BeforebollMid15 and self.FifteenMinTrendStatus=='kongtou': + self.FifteenMinTrendStatus='panzhen' + + with open("datasig15.csv","ab+",) as csvfile: + writer = csv.writer(csvfile) + writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,0,0,self.dealopen]) + + print u"15分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s"%(self.FiveMinTrendStatus,self.FifteenMinTrendStatus) + # 当前无仓位,发送OCO开仓委托 + ''' + if self.pos == 0: + self.intraTradeHigh = bar.high + + if self.FifteenMinTrendStatus=='panzhen': + self.longEntry = self.bollUp15 + self.shortEntry=self.booldown15 + self.buy(self.longEntry, self.fixedSize, True) + self.short(self.shortEntry,self.fixedSize,True) + ''' + #---------------------------------------------------------------------- + def onOrder(self, order): + """收到委托变化推送(必须由用户继承实现)""" + pass + + #---------------------------------------------------------------------- + def onTrade(self, trade): + #打印信息 + print u"委托单成交" + print trade.direction + print trade.offset + print "15min:",self.FifteenMinTrendStatus + print "5min:",self.FiveMinTrendStatus + + # 发出状态更新事件 + orderList=[] + if self.pos > 0 : + orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) + print u"委托止损单,5分钟下轨平仓" + elif self.pos < 0 : + orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) + print u"委托止损单,5分钟上轨平仓" + + #打印信息 + if orderList: + print u"委托单成功单号",orderList + else: + print u"委托单失败" + + + if trade.offset==OFFSET_OPEN: + if trade.direction==DIRECTION_LONG: + self.dealopen=1 + self.FifteenMinTrendStatus='duotou' + self.FiveMinTrendStatus='duotou' + else: + self.dealopen=-1 + self.FifteenMinTrendStatus='kongtou' + self.FiveMinTrendStatus='kongtou' + + if trade.offset==OFFSET_CLOSE: + if trade.direction==DIRECTION_LONG: + self.deal=1 + else: + self.deal=-1 + + + self.putEvent() + + #---------------------------------------------------------------------- + def onStopOrder(self, so): + """停止单推送""" + pass \ No newline at end of file From 56c9fdcda517f9036eadd73a3515cb0802d69a30 Mon Sep 17 00:00:00 2001 From: "vn.py" Date: Fri, 19 Jan 2018 09:43:11 +0800 Subject: [PATCH 5/5] =?UTF-8?q?[Del]=E7=A7=BB=E9=99=A4=E6=97=A0=E7=94=A8?= =?UTF-8?q?=E7=AD=96=E7=95=A5=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/VnTrader/MystrategyBollingerBot.py | 362 -------------------- 1 file changed, 362 deletions(-) delete mode 100644 examples/VnTrader/MystrategyBollingerBot.py diff --git a/examples/VnTrader/MystrategyBollingerBot.py b/examples/VnTrader/MystrategyBollingerBot.py deleted file mode 100644 index d1afb40f..00000000 --- a/examples/VnTrader/MystrategyBollingerBot.py +++ /dev/null @@ -1,362 +0,0 @@ -# encoding: UTF-8 - -""" -仅在知乎Live中分享,请勿外传。 - -基于布林通道通道的交易策略,适合用在股指上5分钟线上。 -""" - -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, BarGenerator, ArrayManager - -import csv -from vnpy.trader.vtConstant import (EMPTY_STRING, EMPTY_UNICODE, - EMPTY_FLOAT, EMPTY_INT) - -from vnpy.event import Event -from vnpy.trader.vtGlobal import globalSetting -from vnpy.trader.vtEvent import * -from vnpy.trader.vtGateway import * -from vnpy.trader.language import text -from vnpy.trader.vtFunction import getTempPath -######################################################################## -class MyBollingerBotStrategy(CtaTemplate): - """基于布林通道的交易策略""" - className = 'MyBollingerBotStrategy' - author = 'yuanhui' - - # 策略参数 - bollWindow = 26 # 通道窗口数 - entryDev = 2 # 开仓偏差 - exitDev = 1.2 # 平仓偏差 - trailingPrcnt = 0.4 # 移动止损百分比 - maWindow = 10 # 过滤用均线窗口 - initDays = 10 # 初始化数据所用的天数 - fixedSize = 1 # 每次交易的数量 - priceTick = 0.2 # 价格最小变动 - - DayTrendStatus='duotou' #DuoTou, KongTou,Panzheng - OnehourTrendstatus='panzhen' - FifteenMinTrendStatus='panzhen' - FiveMinTrendStatus='panzhen' - - # 5Min策略变量 - bollMid = 0 # 布林带中轨 - BeforebollMid=0 #上一根K线的布林线中轨 - bollStd = 0 # 布林带宽度 - bollUp = 0 # 开仓上轨 - Beforebollup=0 #上一根K线的布林线上轨 - bollDown = 0 # 平仓下轨 - beforebooldown=0 #上一根K线的布林线下轨 - - # 15Min策略变量 - bollMid15 = 0 # 布林带中轨 - BeforebollMid15=0 #上一根K线的布林线中轨 - bollStd15 = 0 # 布林带宽度 - bollUp15 = 0 # 开仓上轨 - Beforebollup15=0 #上一根K线的布林线上轨 - bollDown15 = 0 # 平仓下轨 - beforebolldown15=0 #上一根K线的布林线下轨 - - maFilter = 0 # 均线过滤 - maFilter1 = 0 # 上一期均线 - - intraTradeHigh = 0 # 持仓期内的最高点 - longEntry = 0 # 多头开仓 - longExit = 0 # 多头平仓 - shortEntry=0 - shortExit=0 - - deal=0 - dealopen=0 - - - orderList = [] # 保存委托代码的列表 - - # 参数列表,保存了参数的名称 - paramList = ['name', - 'className', - 'author', - 'vtSymbol', - 'bollWindow', - 'entryDev', - 'exitDev', - 'trailingPrcnt', - 'maWindow', - 'initDays', - 'fixedSize', - 'DayTrendStatus'] - - # 变量列表,保存了变量的名称 - varList = ['inited', - 'trading', - 'pos', - 'bollUp', - 'bollDown', - 'bollUp15', - 'bollDown15', - 'FifteenMinTrendStatus', - 'FiveMinTrendStatus'] - - # 同步列表 - syncList = ['pos', - 'intraTradeHigh'] - - #---------------------------------------------------------------------- - def __init__(self, ctaEngine, setting): - """Constructor""" - super(MyBollingerBotStrategy, self).__init__(ctaEngine, setting) - - self.bm = BarGenerator(self.onBar, 5, self.onFiveBar) - self.am = ArrayManager() - - self.bm15 = BarGenerator(self.onBar, 15, self.on15MinBar) - self.am15 = ArrayManager() - with open("datasig.csv","wb+") as csvfile: - writer = csv.writer(csvfile) - writer.writerow(["datetime","open","close","high","low","openInterest","volume","deal","pDown","pUp","dealOpen"]) - with open("datasig15.csv","wb+") as csvfile: - writer = csv.writer(csvfile) - writer.writerow(["datetime","open","close","high","low","openInterest","volume","deal","pDown","pUp","dealOpen"]) - - #---------------------------------------------------------------------- - def onInit(self): - """初始化策略(必须由用户继承实现)""" - self.writeCtaLog(u'%s策略初始化' %self.name) - - # 载入历史数据,并采用回放计算的方式初始化策略数值 - initData = self.loadBar(self.initDays) - for bar in initData: - self.onBar(bar) - - self.putEvent() - - #---------------------------------------------------------------------- - def onStart(self): - """启动策略(必须由用户继承实现)""" - self.writeCtaLog(u'%s策略启动' %self.name) - self.putEvent() - - #---------------------------------------------------------------------- - def onStop(self): - """停止策略(必须由用户继承实现)""" - self.writeCtaLog(u'%s策略停止' %self.name) - self.putEvent() - - #---------------------------------------------------------------------- - def onTick(self, tick): - """收到行情TICK推送(必须由用户继承实现)""" - self.bm.updateTick(tick) - - #---------------------------------------------------------------------- - def onBar(self, bar): - """收到Bar推送(必须由用户继承实现)""" - #self.bm.updateBar(bar) - # 基于15分钟判断趋势过滤,因此先更新 - self.bm15.updateBar(bar) - - # 基于5分钟判断 - self.bm.updateBar(bar) - print u"策略:",self.__dict__["name"] - print u"时间:%s,1分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s,日趋势%s"%(bar.time,self.FiveMinTrendStatus,self.FifteenMinTrendStatus,self.DayTrendStatus) - - #---------------------------------------------------------------------- - def onFiveBar(self, bar): - """收到5分钟K线""" - #计算上一个k线的布林中轨,上轨,下轨 - self.BeforebollMid=self.am.sma(self.bollWindow) - self.Beforebollup,self.beforebooldown=self.am.boll(self.bollWindow,self.entryDev) - # 保存K线数据 - self.am.updateBar(bar) - if not self.am.inited: - return - - # 撤销之前发出的尚未成交的委托(包括限价单和停止单) - self.cancelAll() - orderList=[] - - # 计算指标数值 - self.bollMid = self.am.sma(self.bollWindow) - #self.bollStd = self.am.std(self.bollWindow) - self.bollUp,self.bollDown = self.am.boll(self.bollWindow,self.entryDev) - #self.boolDown = self.bollMid - self.bollStd * self.entryDev - - #maArray = self.am.sma(self.maWindow, True) - #self.maFilter = maArray[-1] - #self.maFilter1 = maArray[-2] - #判断当前5Min布林线趋势状态 - if bar.high > self.Beforebollup: - self.FiveMinTrendStatus='duotou' - elif bar.low < self.beforebooldown: - self.FiveMinTrendStatus='kongtou' - elif bar.low < self.BeforebollMid and self.FiveMinTrendStatus=='duotou': - self.FiveMinTrendStatus='panzhen' - elif bar.high > self.BeforebollMid and self.FiveMinTrendStatus=='kongtou': - self.FiveMinTrendStatus='panzhen' - - if self.DayTrendStatus=='kongtou' and bar.high > self.bollMid15 and self.FifteenMinTrendStatus == 'kongtou': - self.FifteenMinTrendStatus=='panzhen' - if self.DayTrendStatus=='duotou' and bar.low < self.bollMid15 and self.FifteenMinTrendStatus == 'duotou': - - self.FifteenMinTrendStatus=='panzhen' - # 判断是否要进行交易 - print u"5分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s"%(self.FiveMinTrendStatus,self.FifteenMinTrendStatus) - # 当前无仓位,发送OCO开仓委托 - if self.pos == 0: - #self.intraTradeHigh = bar.high - - if self.DayTrendStatus=='duotou' and (self.FifteenMinTrendStatus=='panzhen' or self.FifteenMinTrendStatus=='kongtou'): - orderList=self.buy(self.bollUp15+self.priceTick, self.fixedSize, True) - print u"委托多单,15分钟上轨开仓" - elif self.DayTrendStatus=='duotou' and self.FifteenMinTrendStatus=='duotou' and self.FiveMinTrendStatus=='duotou': - self.longEntry = bar.close - orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) - print u"委托多单,5分钟收盘价开仓" - elif self.DayTrendStatus=='duotou' and self.FifteenMinTrendStatus=='duotou' and (self.FiveMinTrendStatus=='panzhen' or self.FiveMinTrendStatus=='kongtou'): - self.longEntry=self.bollUp - orderList=self.buy(self.longEntry+self.priceTick, self.fixedSize, True) - print u"委托多单,5分钟上轨开仓" - elif self.DayTrendStatus=='kongtou' and (self.FifteenMinTrendStatus=='panzhen' or self.FifteenMinTrendStatus=='duotou') : - self.orderList=self.short(self.bollDown15-self.priceTick, self.fixedSize, True) - print u"委托空单,15分钟下轨开仓" - elif self.DayTrendStatus=='kongtou' and self.FifteenMinTrendStatus=='kongtou' and self.FiveMinTrendStatus=='kongtou': - self.shortEntry = bar.close - orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) - print u"委托空单,5分钟收盘价开仓" - elif self.DayTrendStatus=='kongtou' and self.FifteenMinTrendStatus=='kongtou' and (self.FiveMinTrendStatus=='panzhen' or self.FiveMinTrendStatus=='duotou'): - self.shortEntry=self.bollDown - orderList=self.short(self.shortEntry-self.priceTick, self.fixedSize, True) - print u"委托空单,5分钟下轨开仓" - - - # 持有多头仓位 - elif self.pos > 0: - #self.intraTradeHigh = max(self.intraTradeHigh, bar.high) - #self.longExit = self.intraTradeHigh * (1 - self.trailingPrcnt/100) - #self.longExit = min(self.longExit, self.exitUp) - #self.longExit=self.boolDown - - orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) - print u"委托止损单,5分钟下轨平仓" - # 持有空头仓位 - elif self.pos < 0: - orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) - print u"委托止损单,5分钟上轨平仓" - - with open("datasig.csv","ab+",) as csvfile: - writer = csv.writer(csvfile) - writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,0,0,self.dealopen]) - self.deal=0 - self.dealopen=0 - - - if orderList: - print u"委托单成功单号",orderList - else: - print u"委托单失败" - # 发出状态更新事件 - self.putEvent() - - - def on15MinBar(self, bar): - """15分钟K线推送""" - - #计算上一个k线的布林中轨,上轨,下轨 - self.BeforebollMid15=self.am15.sma(self.bollWindow) - self.Beforebollup15,self.beforebolldown15=self.am15.boll(self.bollWindow,self.entryDev) - - self.am15.updateBar(bar) - - if not self.am15.inited: - return - - # 计算指标数值 - self.bollMid15 = self.am.sma(self.bollWindow) - self.bollUp15,self.bollDown15 = self.am.boll(self.bollWindow,self.entryDev) - - - #判断当前15Min布林线趋势状态 - if bar.high > self.Beforebollup15 and bar.low > self.BeforebollMid15: - self.FifteenMinTrendStatus='duotou' - elif bar.low < self.beforebolldown15 and bar.high < self.Beforebollup15: - self.FifteenMinTrendStatus='kongtou' - elif bar.low < self.BeforebollMid15 and self.FifteenMinTrendStatus=='duotou': - self.FifteenMinTrendStatus='panzhen' - elif bar.high > self.BeforebollMid15 and self.FifteenMinTrendStatus=='kongtou': - self.FifteenMinTrendStatus='panzhen' - - with open("datasig15.csv","ab+",) as csvfile: - writer = csv.writer(csvfile) - writer.writerow([bar.datetime,bar.open, bar.close, bar.high, bar.low,bar.openInterest,bar.volume,self.deal,0,0,self.dealopen]) - - print u"15分钟刷新,趋势状态,5分钟趋势%s,15分钟趋势%s"%(self.FiveMinTrendStatus,self.FifteenMinTrendStatus) - # 当前无仓位,发送OCO开仓委托 - ''' - if self.pos == 0: - self.intraTradeHigh = bar.high - - if self.FifteenMinTrendStatus=='panzhen': - self.longEntry = self.bollUp15 - self.shortEntry=self.booldown15 - self.buy(self.longEntry, self.fixedSize, True) - self.short(self.shortEntry,self.fixedSize,True) - ''' - #---------------------------------------------------------------------- - def onOrder(self, order): - """收到委托变化推送(必须由用户继承实现)""" - pass - - #---------------------------------------------------------------------- - def onTrade(self, trade): - #打印信息 - print u"委托单成交" - print trade.direction - print trade.offset - print "15min:",self.FifteenMinTrendStatus - print "5min:",self.FiveMinTrendStatus - - # 发出状态更新事件 - orderList=[] - if self.pos > 0 : - orderList=self.sell(self.bollDown-self.priceTick, abs(self.pos), True) - print u"委托止损单,5分钟下轨平仓" - elif self.pos < 0 : - orderList=self.cover(self.bollUp+self.priceTick, abs(self.pos), True) - print u"委托止损单,5分钟上轨平仓" - - #打印信息 - if orderList: - print u"委托单成功单号",orderList - else: - print u"委托单失败" - - - if trade.offset==OFFSET_OPEN: - if trade.direction==DIRECTION_LONG: - self.dealopen=1 - self.FifteenMinTrendStatus='duotou' - self.FiveMinTrendStatus='duotou' - else: - self.dealopen=-1 - self.FifteenMinTrendStatus='kongtou' - self.FiveMinTrendStatus='kongtou' - - if trade.offset==OFFSET_CLOSE: - if trade.direction==DIRECTION_LONG: - self.deal=1 - else: - self.deal=-1 - - - self.putEvent() - - #---------------------------------------------------------------------- - def onStopOrder(self, so): - """停止单推送""" - pass \ No newline at end of file