蜗牛博客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三天的价格无误
