蜗牛博客VNPY学习记录:
VN.PY 2.0学习记录一(如何回测)
VN.PY 2.0学习记录二(策略开发)
Vn.py学习记录三(米筐教程)
VN.PY 2.0学习记录四(多线程、多进程)
Vn.py学习记录五–交易时间段及Widgets
Vn.py学习记录六(无界面模拟盘)
Vn.py学习记录七(V2.0.5版本)
Vnpy学习记录八(R-Breaker及pickle)
Vn.py学习记录九(事件驱动引擎)
VN.PY学习记录十(源码概述)
VNPY学习记录11(微信+Vscode)
VNPY学习记录12(父子进程、回调函数)
VNPY学习记录13(部署到云服务器,实现自动交易)
一、策略介绍
日内策略大都以固定价格为参照系,根据前一个交易日的收盘价、最高价和最低价依次计算出六个触发条件价位:昨日收盘价之上趋势情况下的突破买入(Bbreak),震荡冲高回落情况下准备卖出(Ssetup)和反手卖出(Senter)。昨日收盘价之下依次是反手买入(Benter),准备买入(Bsetup),突破卖出(Sbreak)。
为方便起见现只看多头交易。空仓时突破Bbreak开多,类似于突破昨日高点的菲阿里四价策略,区别只在偏移量。持仓时冲高回落,此时的仓位来源有两种情况,一是空仓突破买入后来回落到Bbreak以下,变成持多仓冲高回落;二是在空头反手开多后冲过昨日收盘价的持仓。实际测试中发现反手没有比单独平仓在胜率次均方面优秀,所以反手可以直接变成平仓。于是在昨日开盘价之上就两种情况:突破成功和突破失败。突破成功另外处理当然可以使用均线系统的出场条件,具体方法待以后研究。突破失败实际上变成以突破买入价开仓反手卖出价止损。由此可以看出R-Breaker只能是一个纯粹的日内策略,如果隔夜交易结果一定难看,原因很简单,止盈幅度太小,属于吃苍蝇腿的策略,追求蝇头小利。
显而易见,R-Breaker策略基本上没有新颖之处,胜率一般,实质上是一个菲阿里四价,而且止损幅度小于菲阿里四价,菲阿里四价的止损点在收盘价之下。至于具体的细节,了解即可。
参考:https://blog.csdn.net/S_o_l_o_n/article/details/81366884
根据前一个交易日的收盘价、最高价和最低价数据通过一定方式计算出六个价位,
从大到小依次为:
突破买入价(buy_break)、观察卖出价(sell_setup)、
反转卖出价(sell_enter)、反转买入价(buy_enter)、
观察买入价(buy_setup)、突破卖出价(sell_break)
参考:https://www.sohu.com/a/119798483_505915
生成K线:https://blog.csdn.net/q275343119/article/details/85165752
二、pickle
将数据保存为pickle,方便以后调用。
import pickle data = [0, 1] # 保存 with open('day.pickle', 'wb') as f: pickle.dump(data, f) # 读取 with open('day.pickle', 'rb') as f: b = pickle.load(f) print(b[1])
三天的:
import pickle data = [0, 3, 0] # 保存 with open('3day.pickle', 'wb') as f: pickle.dump(data, f) # 读取 with open('3day.pickle', 'rb') as f: b = pickle.load(f) print(b)
三、策略实现
import pickle from vnpy.app.cta_strategy import ( CtaTemplate, StopOrder, TickData, BarData, TradeData, OrderData, BarGenerator, ArrayManager, ) from datetime import datetime, time class RBreaker(CtaTemplate): author = "蜗牛博客:http://www.snailtoday.com" fast_window = 10 slow_window = 20 fast_ma0 = 0.0 fast_ma1 = 0.0 slow_ma0 = 0.0 slow_ma1 = 0.0 parameters = ["fast_window", "slow_window"] variables = ["fast_ma0", "fast_ma1", "slow_ma0", "slow_ma1"] def __init__(self, cta_engine, strategy_name, vt_symbol, setting): """""" super(RBreaker, self).__init__( cta_engine, strategy_name, vt_symbol, setting ) self.bg = BarGenerator(self.on_bar) self.am = ArrayManager() self.indicator1=0 #反转做空信号 self.indicator2=0 #反转做多信号 #用于记录当天最高价 self.dayMaxPrice = 0 self.dayMinPrice = 0 self.dayClosePrice = 0 self.threeDayPrice = [0,0,0] self.DAY_END = time(15, 00) self.DAY_START =time(9,30) self.bb = 0 self.sw=0 self.bw=0 self.sa=0 self.ba=0 self.sb=0 self.bb=0 self.coeff_w = 0.35 self.coeff_a1 = 1.07 self.coeff_a2 = 0.07 self.coeff_b = 0.25 self.fixedSize = 1 def on_init(self): """ Callself.back when strategy is inited. """ self.write_log("策略初始化") self.load_bar(10) def on_start(self): """ Callself.back when strategy is started. """ self.write_log("策略启动") self.put_event() def on_stop(self): """ Callself.back when strategy is stopped. """ self.write_log("策略停止") self.put_event() def on_tick(self, tick: TickData): """ Callself.back of new tick data update. """ self.bg.update_tick(tick) def on_bar(self, bar: BarData): """ Callself.back of new self.bar data update. """ # 全撤之前发出的委托 #self.cancelAll() # 保存K线数据 am = self.am am.update_bar(bar) if not am.inited: return #获取前一分钟的收盘价和最高价 min_1_close=am.close_array[-2] min_1_high=am.high_array[-2] self.f1 = open('break.txt','a') self.__timeWindow(bar.datetime) if self.openWindow: #打开前两天价格记录文件,并导入为一个self.twoDayPrice的列表,self.twoDayPrice[0]代表前天价格,self.twoDayPrice[1]代表昨天 with open('3day.pickle', 'rb') as f: self.threeDayPrice = pickle.load(f) self.f1.write("-"*100) self.f1.write('\n') self.f1.write("前一天最高、最低、收盘价格为{}".format(self.threeDayPrice)+'\n') self.f1.write("-----当前时间{}".format(bar.datetime)+"\n") self.dayMaxPrice = bar.high_price self.dayMinPrice = bar.low_price #计算前一日最高价、最低价和收盘价 high = self.threeDayPrice[0] low = self.threeDayPrice[1] close = self.threeDayPrice[2] #计算指标数值 self.sw=high+self.coeff_w*(close-low) self.bw=low-self.coeff_w*(high-close) self.sa=self.coeff_a1*(high+low)/2-self.coeff_a2*low self.ba=self.coeff_a1*(high+low)/2-self.coeff_a2*high self.sb=self.bw-self.coeff_b*(self.sw-self.bw) self.bb=self.sw+self.coeff_b*(self.sw-self.bw) if bar.high_price > self.dayMaxPrice: self.dayMaxPrice = bar.high_price if bar.low_price < self.dayMinPrice: self.dayMinPrice = bar.low_price # 判断是否要进行交易 ##趋势 if min_1_close<=self.bb and bar.close_price>self.bb: if self.pos==0: self.buy(bar.open_price,self.fixedSize) if self.pos <0: self.cover(bar.close_price,abs(self.pos)) if min_1_close>=self.sb and bar.close_price<self.sb: if self.pos==0: self.short(bar.open_price,self.fixedSize) if self.pos>0: self.sell(bar.close_price,self.pos) ##反转 ###多单反转 if bar.high_price>self.sw and bar.close_price>self.sa: self.indicator1=1 if self.indicator1==1 and bar.close_price<self.sa: self.indicator1=0 if self.pos>0: self.sell(bar.close_price,self.pos) self.short(bar.open_price,self.fixedSize) ###空单反转 if bar.low_price<self.bw: self.indicator2=1 if self.indicator2==1 and bar.close_price>self.ba: self.indicator2=0 if self.pos<0: self.buy(bar.close_price,abs(self.pos)+self.fixedSize) #当天平仓 if bar.datetime.time()>time(14,55): if self.pos>0: self.sell(bar.close_price,self.pos) if self.pos<0: self.cover(bar.close_price,abs(self.pos)) if self.closeWindow: self.threeDayPrice[0] = self.dayMaxPrice self.threeDayPrice[1] = self.dayMinPrice self.threeDayPrice[2] = bar.close_price #将最近一天的最高、最低、收盘价保存到pickle文件 with open('3day.pickle', 'wb') as f: pickle.dump(self.threeDayPrice, f) self.f1.close() #发出状态更新事件 self.put_event() def __timeWindow(self,dt): """交易与平仓窗口""" self.openWindow = False self.orderWindow = False self.tradeWindow = False self.closeWindow = False self.afterCloseWindow = False #用于获取开盘价 if dt.hour == 9 and dt.minute == 31: self.openWindow = True return if dt.hour == 9 and dt.minute > 31: self.tradeWindow = True return if dt.hour == 10: self.tradeWindow = True return if dt.hour == 11 and dt.minute <= 30: self.tradeWindow = True return if dt.hour == 13: self.tradeWindow = True return if dt.hour == 14: self.tradeWindow = True return #清仓时段 if dt.hour == 15 and dt.minute == 00: self.closeWindow = True return def on_order(self, order: OrderData): """ Callself.back of new order data update. """ pass def on_trade(self, trade: TradeData): """ Callself.back of new trade data update. """ self.put_event() def on_stop_order(self, stop_order: StopOrder): """ Callself.back of stop order update. """ pass
参考:https://blog.csdn.net/tt07406/article/details/81988898
四、效果展示
五、获取前一天的OCLH价格
通过EXCEL核实,上面的6月4,5,6三天的价格无误