1_止损是最高行为准则
回顾前面的一些策略的学习,我们谈到过很多的买入策略,包括股票软件上的大多数指标也只是简单的提供买入点的策略,而对于卖出点的策略涉及很少。其中,双均线类的策略非常容易制作成组的买入和卖出,因为它们总是会有金叉和死叉,属于自带止损或止盈的策略,但带来的问题也会非常的多,其中主要的就是骗线以及对于成交的时间的误判,往往产生金叉的当天那根阳线比较长,成交量大多也放大,而正规的下单是按照第二天的开盘价去成交的,即使是Cheat-On-Close也是按收盘价去成交的,通常应该是买在了最高点。从前面我们的回测经验来看,后续的走势是有比较大概率回调的,这个很常见,趋势没有走出来之前,向上向下的可能性都有,但趋势走出来向上再追进去往往容易高位站岗。
于是,如果被骗进去了又遇到向下的情况下,怎么保住自己的本金?股市有句老话:市场从来不会错,而你的想法常常是错的。而“止损、止损、止损”是炒股行的最高行为准则。
只赢不输的情况是不可能的,但败而不倒却是可以的,所以我们必须提前掌握好止损的策略,使用backtrader来回测各种不同的止损的策略能够让我们先出适合自己的止损方法,即能够败而不倒,还能够不焦虑。 任何时间任何情况下都不要去赌某支股票它会涨起来,一旦涉及到赌,通常的结果都是十赌九输,伤心、断肠。
2_止损与止盈的策略研究
2.1_参考文档
- 【止损】 止损/止盈 方案目录 必读 | RiceQuant米筐量化社区 交易策略论坛
- 交易10年,我总结了几套经典的止盈策略,适合不同类型的交易者,- 知乎
- 史上最全3种盈亏比模式详解 | 爱财有道
- #量化交易# 十种经典止损出场策略 ... - 雪球
- 供参考:个人股票投资者经典止损止盈策略 .. - 雪球
2.2_固定止损与止盈
单个固定止损无法形成买卖策略的闭环,如果买入后股价一直涨,就一直不会卖出。所以在用任意一种策略买入后,固定止损通常都跟另外一个卖出策略组合产生闭环,这个策略可以是死叉,可以是止盈线等。这里我们先采用固定盈亏比止损止盈的策略。
关于盈亏比的概念及常识的理解,可以从“史上最全3种盈亏比模式详解”的参考文档中学习。需要注意的是,盈亏比不是乱定的,包括止损线设定在哪里都是需要有根据的进行计算得到的。每支股票的股性不同,它每天的振幅以及阶段波动幅度是不一样的,如果都采用统一的下跌7%或下跌10%止损,实际情况是不合适的。
A_股票软件的基本止损和止盈线
先在股票软件中初步实现止损线和止盈线的显示
ma5:=MA(C,5);
ma10:=MA(C,10);
xh1:=CROSS(ma5,ma10);
xh2:=CROSS(ma10,ma5);
L1:=IF(xh1,C*0.95,C);
H1:=IF(xh1,C*1.10,C);
N1 := BARSLAST(xh1);
N2 := BARSLAST(xh2);
B1:= REF(xh1,N1) AND N2>N1; // B1是金叉到死叉的多日阶段
DRAWICON(xh1,C,1); // 绘制向上箭头
Ninit:=BARSLAST(xh1);
S1: IF(B1,0.95*REF(C,Ninit),DRAWNULL); //绘制止损线
Sup:IF(B1,1.1*REF(C,Ninit),DRAWNULL); //绘制止盈线
就可以得到如下图所示,当510金叉的时候,在-5%和+10%的位置画止损和止盈的线
B_股票软件止损或止盈的触发
看上面的图,一个简单的画止损线和止盈线的功能是实现了,但还存在很多的问题,比如说触发后上一次的既没有止损也没有止盈,但又发生510金叉了;又比如说连卖出的箭头都没有画......
所以接下来我们需要做一下闭环的触发,即一次买入后必须对应一次卖出。这个在双均线的策略中我们已经完成过,简单的逻辑就是计算金叉(买入点)和死叉(卖出点)到当前的周期数,然后再分别判断在死叉到现在的周期数里,买入点的次数是否大于1;以及金叉到现在的周期数里,卖出点的次数是否大于1,然后只显示第1个买点和第1个卖点即可。
B1:=CROSS(C,LB); //上穿下轨为买点b1
S1:=CROSS(UB,C); //下穿上轨为卖点s1
N1:=BARSLAST(B1); //记录最近1次买点的周期
N2:=BARSLAST(S1); //记录最近1次卖点的周期
B3:=COUNT(B1,N2)>1; // 根据最近1次卖出的位置到现在的的买点b1出现的次数是否大于1
// True 代表卖掉后已经出现至少2次买点了
S3:=COUNT(S1,N1)>1; // 同上,True代表买入后至少出现2次卖点了
DRAWICON(B1 AND NOT(B3),LB,7); // 只显示第1个买点
DRAWICON(S1 AND NOT(S3),UB,8); // 只显示第1个卖点
但在这里并不是双均线的简单金叉和死叉,卖出点可能是由于小于止损值,也可能是大于止盈值,并且由于没有一个全局变量来记录止损和止盈数值,还需要从前一个数值来沿用。
ma5:=MA(C,5);
ma10:=MA(C,10);
xh1:=CROSS(ma5,ma10);
L1:=IF(xh1,C*0.95,C);
H1:=IF(xh1,C*1.10,C);
N1 := BARSLAST(xh1);
L1ref:IF(N1>0,REF(L1,N1),(REF(L1,N1)+REF(H1,N1))/2);
H1ref:IF(N1>0,REF(H1,N1),(REF(L1,N1)+REF(H1,N1))/2);
xhs1:=CROSS(C,H1ref) AND H1ref <>0; // 上穿止盈
xhs2:=CROSS(L1ref,C) AND L1ref <>0; // 下穿止损
xh2:= xhs1 OR xhs2; // 止损或止盈
N2:= BARSLAST(xh2);
S3:=COUNT(xh2,N1)>1;
DRAWICON(xh2 AND NOT(S3),C,2);
DRAWICON(xh1 ,C,1); // 绘制向上箭头
严格的讲这里的代码仍没有完全满足要求,因为总要有一个赋初值,而我们用510金叉初始化,就不能再使用xh2的卖出语句再对xh1进行重新赋值,所以最后的结果就是510只要金叉就会重新开始计算,但过程中只会出现1次卖出点。也就是如果这一轮没有满足止损或止盈的条件,那么就直接到下一轮去重新判断,其实这样操作也可以,只不过在连续下跌的过程中,止损点会不断下移,而在连续上涨的过程中,止盈点也会不断上移。
C_backtrader实现固定止损止盈
在backtrader中来实现反而会比股票软件上绘图要简单的多,这是基于position的判断来的。我们先采用KDJ金叉且K小于50为买入条件,在买入的同时记录self.cutshort和self.cutlong的值;然后在else中判断是否产生了止损或止盈,条件满足就卖出。
class cutshort1(BaseSt):
params=(('log_off',0),('stra_name','固定止损止盈'),('maperiod',18),)
def __init__(self):
self.order=None # 开局设定
self.kd = bt.indicators.Stochastic(self.data)
self.sma = bt.indicators.SMA(self.data.close, period=20)
self.crsup = bt.indicators.CrossUp(self.kd.l.percK, self.kd.l.percD)
self.crsdn = bt.indicators.CrossDown(self.kd.l.percK, self.kd.l.percD)
self.cutshort = 0 #止损点
self.cutlong = 0 #止盈点
def next(self):
if self.order:
return
if not self.position: # 如果没有持仓则买入
if (self.crsup[0]==True) & (self.kd.l.percK[-1]<50) :
self.cutshort = self.data.close[0] * 0.95 # 止损点赋值
self.cutlong = self.data.close[0] * 1.1 # 止盈点赋值
self.order = self.buy()
else: # 在卖出处理止损止盈
if (self.data.close[0]< self.cutshort) & (self.data.close[-1]> self.cutshort):
self.order = self.sell() # 处理止损
elif (self.data.close[0]> self.cutlong) & (self.data.close[-1]< self.cutlong):
self.order = self.sell() # 处理止盈
run_main_plot(cutshort1, 2)
-----------------
当前使用策略为 固定止损止盈 , 当参数1为 18 ,参数2为None ,
期末总资金 111950.30 盈利为 11950.30 总共交易次数为 11 ,交易成功率为 45.5%
这一段的回测收益率11.95%,还是不错的,我们再测一下KDJ金叉死叉的策略看到收益率只有7.85%,可以看到当采用了固定盈亏的卖出策略后,收益率是明显增加的。
---------------
当前使用策略为 KDJ无止损止盈 , 当参数1为 18 ,参数2为None ,
期末总资金 107848.20 盈利为 7848.20 总共交易次数为 27 ,交易成功率为 37.0%
我们再换一支股票进行回测,回测的结果与图片对比如下,上面是固定盈亏的卖出策略,下面是KDJ的死叉卖出策略,可以明显的看到,固定盈亏的触发频率远低于KDJ,虽然在连续下跌的过程中,KDJ反而止损更快速会使每次亏损数值并不大,但触发次数多导致亏损也差不多;而在振荡上涨的过程中,KDJ金叉死叉过于频繁,会产生很多细碎的交易,出现很多的蓝色叉叉,且红勾的收益也经常不理想,由图相比较而言,固定盈亏的卖出策略减少了交易的次数,并且能得到每次红勾都是比较稳定的10%,最终收益率是9.6%,比KDJ的金叉死叉策略的-0.4%要好上不少。
需要说明的是,如果遇到连续向下的股票,有的使用固定盈亏的亏损反而会比KDJ的金叉死叉要严重,因此不能说固定盈亏就一定会是更好的策略。这个还是要根据股票的特性,以及它每一波的涨跌幅度来计算的,有的股票偏偏每次只涨到9%就又跌回去了,那么始终就无法触发卖出,就会一直在坐过山车。后续我们有时间再来研究如果根据每支股票的ATR来计算它的有效盈亏百分比。
D_在条件单中使用止盈止损
固定的止损与止盈功能,在很多股票软件APP上智能条件单中已经提供了这个功能,可以直接使用。这个条件单的用法就是在你已经买入的前提下(为什么买入的原因不需要管),可以给它设置固定的止盈条件和止损条件。
说真的,对于一般炒股的人来说,这个功能已经很棒了,我们也不需要花很多的时间来学习量化,也不需要交钱给券商来开通量化交易的接口,在免费的APP上就可以免费使用了。当你使用它的时候,你也变成量化交易了~
最最重要的是,完成设置后你在任何情况下都可以没有心理负担,由条件单自动帮你完成止损和止盈,既遵守了交易的纪律,又不会焦虑。而且你设好后就不用去管它,它也不会忘记。很多人炒个股天天盯盘,每时每刻都忧心忡忡,很快就熬白了头,何苦来哉。当你能够基础的使用止盈止损条件单的时候,甚至于一天都不需要看盘,还能感觉自己运筹帷幄之中,决胜千里之外~
唯一要做的,还是要根据这支股票当前的一些指标来计算它合理的止盈和止损百分比,这个是决定性的东西。
2.3_动态止损与止盈
固定止损和止盈的设置,往往跟运气有很大的关系,也就是如果运气好,止盈止损的价格刚刚好,那么收益率非常高,但如果运气不好,例如止盈设了10%但股票价格恰好到9.9%就回落了,那么又一切都成浮云。另外一类情况,就是一卖就起飞的这种,就会让大多数人感到懊悔。所以又出现了动态止盈这种策略。
A_条件单动态止盈
a) 跟踪止损
跟踪止损考虑的是这支股票的回撤,这种方式卖出的价位会随着最高价的变化而变化。我们看上面的图,盈利的最右边有个“回落”的开关,通过这个开头可以低配的实现最大回撤进行止盈或止损的一种方式。
这个通常是用于拉升过程中的洗盘,比如拉升了10%,回落5%,再拉到20%这类会比较有效,但对于人气股几乎没什么用。往往只能用于那种走上升趋势的行业ETF,小步向上且回落不严重,还是有希望赶上几波上涨,但更多的情况反而是回落设置的不好要么本来没涨多少回落下去又白玩,要不然就是你回落止盈后它再疯狂拉升,反而收益率上没有固定止损止盈来的高。
人生总是难免会遇到几次这种单边上涨不回头的极限时刻,我们也可以称之为高光时刻,如果错过了会后悔好久。而且“让利润奔跑”是很多人难以企及的梦,为了这不到1%的机会,仍然有必要使用最大回撤止盈,但具体设定的超出界线以及回落的值需要在过程中适当调整,并且可以使用阶梯式以及分仓操作。
这个功能在条件单上很容易实现,但潜在的逻辑以及针对个股的计算方法就显得格外重要,开始的时候切莫报有超过自己水平的希望,你随意设置的一个值很可能一点用都没有,反而让你原本固定止盈的收益大幅度降低。
b) 阶梯止损
所谓阶梯,就是字面上的意思,上台阶。所以阶梯止损或止盈就是根据上涨或下跌的幅度,人为设置台阶,进行分段的控制。这个在实际的应用中实现是很容易的,就是把止盈止损的条件单外面再套一个条件单,或者当第1个条件单触发后再重新根据当前的情况开启一个新的条件单。
在实际应用中最普遍的问题是第1个条件单触发完成后,第2个条件单沿用了第1个或者没有回到全局视野去重新计算分析而草率设定了第2个条件单,这就会使得后续的条件单不契合股票价格和成交量的变化,从而给人条件单不好用的错觉。
c) 混合止盈或止损
混合的方式有很多,比如时间+阶梯,又比如超出固定止盈的线后根据MA10的移动平均线进行止盈,或者超出固定止盈线后根据两个最低点连线延长做支撑跌破止损的方式。不过这些自由度更大的方式在当前的条件单里面是直接做不了的,毕竟移动平均线和趋势线一直都在动态变化着,每天的值会不一样,这就不是定值的止盈止损条件单能做到的。
B_股票软件上设置动态止盈线
股票软件上主要提供的帮助就是画线,从视觉角度辅助我们进行止损或止盈的操作。
a) 最大回撤止损
在这里,我们先去掉止盈的部分,只看止损。具体的策略是在买入点计算出止损的位置,然后5天内严格止损(下图绿框左起第4个),但5天后根据最高值重新计算止损线位置,只要最高值有提升那么最后止损的位置一般都会比最初的止损线高,即减少了亏损;如果遇到一波较大幅度的增长(如下图红框)则能够得到一定的收益。
如上面所言,最大回撤止损在收益率上通常是没有固定止盈止损计算比较好的情况下来的高的,但一旦遇到涨幅不正常的大的妖股的时候,最大回撤不容易卖飞,当然这需要看运气了。由于这项原因,我们不在最大回撤止损策略中使用止盈的线,如果添加了止盈的线,大多的时候短期能获取到比较多次的盈利,但容易错过急涨。其实这也是为什么买入的前5天不根据最高值调整止损线的原因,这些策略短期都看上去能小赚,但容易踏空。
MA5:MA(C,5);
MA10:MA(C,10);
B1:=CROSS(MA5,MA10);
DRAWICON(B1,C,1);
N1:=BARSLAST(B1);
SCut:=REF(C,N1)*(100-M2)/100;
sHi:=HHV(H,N1+1);
sHicut:=sHi*(100-M2)/100;
s1:IF(SCut<=sHicut AND N1>=4,sHicut,SCut);
s3:=CROSS(s1,C);
s4:=IF(C<=s1,1,0); // 不适合使用cross,因为很容易出现最高值超过但几天的收盘价都不触发cross
N2:=BARSLAST(s4);
s5:=COUNT(s4,N1)>1;
DRAWICON(s4 AND NOT(s5) ,C,2); //只显示1次卖点
b) 混合止盈策略
可以在股票软件里实现混合止盈的策略,仍然以5-10金叉买入为例,金叉后接上涨的概率与下跌的概率是5-5开,上涨能达到固定止盈的概率又比较低,当超过固定止盈的点位后,我们又不希望等它回撤5%或10%,这里一般可以通过移动平均线或趋势线做支撑,当收盘价跌破支撑的时候,完成止盈操作。
见上图,股价突破固定涨幅之后,就根据MA7的移动平均线进行止盈,这里选择移动平均线的周期大小就至关重要了,有些股票有时候不破MA20就能一直向上,设置周期为20就可以吃上很大一个波段,比如左起第一个红框,如果是MA20那么就不会触发卖出,可以到后续的更高的位置进行卖出。但周期数偏大的缺点就是最后一次的回落也相当的大,往往总涨幅的1/3会被回落给吃掉。
而如果使用比较小的周期,回落幅度就会小很多,但是又很容易被洗出来;对于设置小周期的混合止盈策略而言,要能添加后续的补救措施比如跌破MA5止盈卖出了还可以在下次上穿MA5时再触发买入等,这样的策略会比较有难度进行融合到一起,比分段控制策略甚至更麻烦一些。
ma5:=MA(C,5);
ma10:=MA(C,10);
xh1:=CROSS(ma5,ma10);
L1: IF(xh1,C*0.95,C);
H1: IF(xh1,C*1.10,C);
xh2:=CROSS(ma10,ma5);
N1 := BARSLAST(xh1);
N2 := BARSLAST(xh2);
B1:= REF(xh1,N1) AND N2>N1;
DRAWICON(xh1,C,1);
Vinit:= 0.93*IF(xh1, C, 0);
Ninit:= BARSLAST(xh1);
S1: IF(B1,(1-KS*0.01)*REF(C,Ninit),DRAWNULL);
Sup:=IF(B1,(1+YL*0.01)*REF(C,Ninit),DRAWNULL);
Su2:IF( C>Sup AND MA(C,7)>Sup , MA(C,7),Sup),colorred;
DRAWICON(CROSS(Su2,C),C,2);
DRAWICON(CROSS(S1,C),C,2);
C_在backtrader中动态止盈
a) 跟踪止损(最大回撤)
采用最大回撤止损的方式
class cutshort2_D(BaseSt):
params=(('log_off',0),('stra_name','动态止盈'),('M2',5),)
def __init__(self):
self.order=None # 开局设定
# ......
self.cutshort = 0 #止损点
self.cutlong = 0 #止盈点
self.dynamicut = False # 动态计算 在买入后开启
def next(self):
if self.order:
return
if self.dynamicut : # 买入后开启动态计算
if self.data.high[0] > self.cut_base : # 只有向上止损点上移
self.cut_base = self.data.high[0]
self.cutshort = self.cut_base * (100-self.p.M2)/100;
if not self.position: # 如果没有持仓则买入
if (self.crsup[0]==True) & (self.kd.l.percK[-1]<50) :
self.dynamicut = True
self.cut_base = self.data.close[0]
self.buy_base = self.data.close[0]
self.cutshort = self.data.close[0] * (100-self.p.M2)/100 # 止损点赋值
self.order = self.buy()
else: # 在卖出处理止损止盈
if (self.data.close[0]< self.cutshort) & (self.data.close[-1]> self.cutshort): # 下穿止损线卖出
self.order = self.sell()
self.dynamicut = False
run_main_plot(cutshort2_D, 2)
---------------
当前使用策略为 动态止盈 ,
期末总资金 113903.61 盈利为 13903.61 总共交易次数为 15 ,交易成功率为 46.7%
run_main_plot(cutshort2_D, 3)
---------------
当前使用策略为 动态止盈 ,
期末总资金 99047.07 盈利为 -952.93 总共交易次数为 21 ,交易成功率为 38.1%
对比前面固定止损止盈以及KDJ无止损止盈策略的收益
当前使用策略为 固定止损止盈 ,
期末总资金 111950.30 盈利为 11950.30 总共交易次数为 11 ,交易成功率为 45.5%
当前使用策略为 固定止损止盈 ,
期末总资金 109659.60 盈利为 9659.60 总共交易次数为 13 ,交易成功率为 46.2%
------------
当前使用策略为 KDJ无止损止盈 ,
期末总资金 107848.20 盈利为 7848.20 总共交易次数为 27 ,交易成功率为 37.0%
当前使用策略为 KDJ无止损止盈 ,
期末总资金 99559.86 盈利为 -440.14 总共交易次数为 33 ,交易成功率为 30.3%
可以看到,对于某些赚钱比较多的股票,动态止盈>固定止盈> KDJ金叉死叉,但对于其他一些股票,动态止盈并不是最好,反而是最差的那个。根据下图与上文的对比,可以看到由于下跌过程中仍有K线的最高值增加,这就造成止损的线上移,更频繁的进行了止损,反而由于次数增多而亏损更大,而对于上升过程中,比较多的回撤止损造成收益比固定止盈要低5个点。
所以综合下来,仍然是不同的股票适合不同的止损策略,还有就是尽量不要在下跌趋势中开仓买入,这个后续我们在分段控制中再详细讨论。
b) 混合止盈策略
在backtrader中,混合策略的自由度非常高,我们不仅可以根据判断选择固定止盈或者某条移动平均线止盈,而且可以采用滤波的算法,让止盈线计算出比较优的值。甚至后续我们还可以应用卡尔曼滤波器等方式进行滤波。
在刚开始的时候不要好高骛远,先实现一个固定止盈和移动平均线的滤波卖出策略:
import numpy as np
class cutshort4_D(BaseSt):
params=(('log_off',0),('stra_name','混合止盈'),('maperiod',18),('dyn_short',0.95),('dyn_long',1.06),)
def __init__(self):
self.order=None # 开局设定
#......
self.cutshort = 0 * self.data.close
self.cutlong = 0 * self.data.close
self.dynamicut = False # 动态计算 在买入后开启
self.ramp = list(np.linspace(1, 0 , 10)) # 滤波系数
def next(self):
if self.order:
return
if self.dynamicut : # 买入后开启动态计算
if self.data.high[0] > self.cut_base : # 只有向上止损点上移
self.cut_base = self.data.high[0]
self.cutshort[0] = self.cut_base * self.p.dyn_short
else:
self.cutshort[0]= self.cutshort[-1]
self.cutlong[0] = self.cutlong[-1] # cutlong延续
if self.data.close[0] > self.cutlong[0]:
if self.sma1 > self.cutlong :
if self.icnt <20 :
self.cutlong[0] = self.sma1[0]* self.ramp[self.icnt] + self.sma2[0]*(1-self.ramp[self.icnt])
self.icnt +=1
else:
self.cutlong[0] = self.sma2[0]
else:
pass
if not self.position: # 如果没有持仓则买入
if (self.crsup[0]==True) & (self.kd.l.percK[-1]<50) :
self.dynamicut = True
self.cut_base = self.data.close[0]
self.buy_base = self.data.close[0]
self.cutshort[0] = self.data.close[0] * self.p.dyn_short # 止损点赋值
self.cutlong[0] = self.data.close[0] * self.p.dyn_long # 止盈点赋值
self.icnt = 0 # 重置
self.order = self.buy()
else: # 在卖出处理止损止盈
if (self.data.close[0]< self.cutshort) & (self.data.close[-1]> self.cutshort): # 下穿止损线卖出
self.order = self.sell()
self.dynamicut = False
elif (self.data.close[0]< self.cutlong) & (self.data.close[-1]> self.cutlong): # 下穿止盈线卖出
self.order = self.sell()
self.dynamicut = False
run_main_plot(cutshort4_D, 2)
-------------
当前使用策略为 混合止盈 ,
期末总资金 118000.14 盈利为 18000.14 总共交易次数为 15 ,交易成功率为 46.7%
c) 在backtrader图中添加动态止损线
从回测的数据来看,对于合适的股票,混合止盈的方式收益相当的高,达到了18%,但在backtrader里我们很难根据图线对它有个直观的认识,在这种情况下,可以简单的在init()里对止盈线和止损线进行绘制。后续还可以把它做成指标,通过指标的属性绘制图线。
self.cutshort = 0 * self.data.close #止损点
bt.LinePlotterIndicator(self.cutshort, name='cut-line', subplot=False)
self.cutlong = 0 * self.data.close #止盈点
bt.LinePlotterIndicator(self.cutlong, name='cut-long', subplot=False)
最后输出的图线示例如下:
3_在backtrader中回测
3.1_各种止损策略回测
现在,把上面完成的三个止损策略放到我们的窗口程序中去,选择多支股票进行回测,得到的结果如下图所示:
首先,不要盲目的下定义哪个止损策略更好,因为目前我们使用的都是定死的5%回撤止损,各支股票它的股性是不同的,这个止损或止盈的幅度不能是固定的,要根据每支股票的近期情况进行估算。
估算一般会使用到ATR即所谓的真实涨跌值,前面我们也说到过股价数量级不同则ATR的绝对值对于多支股票没有参考意义,需要去除以它前一天的收盘价得出一个百分比的数值。
这样我们根据每支股票的近期的ATR百分比的情况(某个参考文档中建议使用22日平均ATR)再设定的止损幅度就能够跟这支股票有比较好的关联性。
然后,仅根据这些回测出的数据来看,KDJ的灵敏度非常高,因此用KD金叉买入一般都不太会错过大的行情,而且无论是固定止损,回撤止损还是混合止损策略,都会把总交易次数给降下来;其中最大回撤止损有时候把2年的总交易次数降到个位数,胜率也会增大,而且收益还不错。
3.2_将买入与卖出的策略分开来
把卖出的止损策略写到backtrader的程序中去的时候,就会发现一个问题,即前期写好的策略都是既有买入又有卖出的,但如果卖出采用止损策略则需要重新写,每一个买入策略都要重写,如果我的止损策略是3个,则重写的策略数为3N个,这样的重复劳动是低效率的。
这里萌生出把买入和卖出策略分开来写的想法,还不成熟。一种思路是把这些都做成indicators,那么在原来策略类里面调用indicators再做个简单判断就可以卖出了。另一种思路是买入和卖出分别继承自买入类和卖出类,在策略类中再分别调用买入或者卖出。
这些思路可以慢慢考虑起来了,后续的分段控制,分仓控制,多因子卖出等更高级的应用可能要基于这个才能做。
4_小结
其实去年底已经在研究止损和止盈的策略在backtrader中的实现了,止损是在股市生存下去的最高准则,而不止盈很容易坐过山车,所以一直觉得有必要把止损的策略总结一下,并且在backtrader中回测一下。只是今年至今为止都没有什么空闲的时间,包括股票开市的那4个小时都基本上没什么空打开APP来看一下。这一段时间在各种尝试条件单的使用,包括条件单挂单、反弹买入、回落卖出、网格交易以及止损止盈等,通过晚上设置好条件单让它们第二天自己去交易。有的时候网格交易买点和卖点准的出奇,但有的时候会滑点比如卖出订单已经触发了但没有成交然后回落把买入成交了,还有的时候暴跌的过程中连续买入把自己搞成重仓亏损严重,暴涨的时候连续卖出结果总的收益一点点......
所以条件单是好东西,但不能乱用,它需要基于量化计算和回测来制定和应用比较合理的条件单策略和设定值,这一节把止损的内容先了结了,后面才可以聚焦到条件单的应用上来。