目录
该系列原发表于知乎(ChristopherShen - 知乎),但最近知乎删我文章,还不给理由,就转移来CSDN了。
1.背景和目标
上一次编写和使用小蓓机器人后,积累了一些对接实盘交易接口的经验,同时也坚定了我寻找完全自动化交易算法的决心。
跟一些朋友交流之后,得到了一些量化的思路,其中最易实现的应该是“隧道交易法”,只需2条ema即可,于是决定先编写隧道交易机器人。
2.算法介绍
据这位朋友介绍,隧道交易法出自于youtuber:金老师的看盘室
金老师讲解视频:
金老师的讲解非常清晰!根据金老师的方法,我首先在TradingView上编写了pine脚本:
https://cn.tradingview.com/script/s6lXtVqy/
抽查了一些case,感觉效果很好,比如下图的SPY日线:8次预测(5次做多、3次做空),7次正确!(红线是止损线,绿线是按盈亏比1:1设置的止盈线)
算法原理如下:(摘自我的TradingView)
这是一套完全根据均线进行交易的指标体系,属于右侧交易,思路如下:
(1) 基本趋势(大趋势)
短期均线高于长期均线时,是上涨趋势;反之,是下降趋势。
暂定短期均线为ema12,长期均线为ema169。
(2) 第一种买入点(或做空点):趋势确立
从上涨趋势确立的那根bar开始,第一个出头的bar,是第一买入点。(出头,是指收盘价高于开盘价,且高于前一根bar的高点)
从下降趋势确立的那根bar开始,第一个落尾的bar,是第一做空点。(落尾,是指收盘价低于开盘价,且低于前一根bar的低点)
(3) 第二种买入点(或做空点):拉回时的买入点(或反弹时的做空点)
拉回时(回调时)的买入点,是指大趋势是上涨,但小趋势是下跌,当明确下跌结束时,可以买入。
这里需要定义2个概念:“拉回(回调)”和“下跌结束”。拉回的定义是,大趋势是上涨时,bar跌破长期均线,此时短期均线仍高于长期均线;下跌结束的定义是,出头且ema12在上升。
同理可知什么是“反弹时的做空点”:
大趋势是下跌,但小趋势是上涨,当明确上涨结束时,可以做空。
(4) 止损位和止盈位的设置
做多时:
止损位:买入点前一根bar的低点。
止盈位:止损位确定后,按盈亏比1:1确定止盈位。(默认值为1,用户可以修改)
做空时:
止损位:买入点前一根bar的高点。
止盈位:止损位确定后,按盈亏比1:1确定止盈位。(默认值为1,用户可以修改)
3.机器人参数
实盘做起来之后,发现还是有一些难点和细节需要敲定,同时也是日后迭代可以改进的地方:
- 止盈位如何确定?除了确定暂时先使用盈亏比1:1外,还加入了“移动止盈”功能,或叫追踪卖出,这一功能的本意是:为了防止卖飞,达到止盈位时不立即平仓,而是准备下一个止损单,止损价比最高价(建仓以来)低一点。我目前的参数是:离止盈位还差0.2%时开启移动止盈,移动比例(追踪比例是0.3%),即盈亏比最低值为0.5:1。这么设计也是经验之谈,看到了一些case,离止盈位就差一点,就趋势反转,止盈变止损。
- 等候天数如何确定?(是否允许过夜?)暂定为不过夜,经验之谈,对隔夜的跳空低开有阴影。
- 如何结束交易?若股价到达止损位或止盈位(移动止盈),则正常结束;但若一直未达到,则:收盘前10分钟市价清仓。
- 资金(仓位)如何分配?暂定:交给机器人1w刀,每只股票可用1k刀,即最多同时入场10只股票。弊端:第11信号出现时不能入场;股价超过1000刀的股票不予考虑(如亚马逊和谷歌)。
- 是否包括盘前盘后交易?不包括,因为盘前盘后不能下市价单,市价单可以保证买入卖出一定成功。
- bar未走完时的信号采用吗?不采用。见到一些case是bar未走完就出信号了,等bar走完信号消失,这种信号不稳定。最简单的例子就是刚开盘5分钟时猛涨,以为这根bar是阳线,等30分钟走完,变成阴线了。弊端是可能会错失较好的入场位,比如信号出现的bar猛涨,之后的bar也猛涨。
4.实盘测试(进行中)
隧道交易法,我个人感觉有一个弊端,就是信号比较少,而且持股时间不能太短,为了解决这个问题,我实盘时使用了30分钟K线,而且选股范围扩大为每日成交额的top200。
经模拟盘测试,每日信号较多,所以我过滤掉了做空信号(也担心券商对某些股票不支持做空)。
第1天实盘:10月6日,周三
前半个交易日bug不断,错失了一些信号,后半日较为稳定。
本金1w刀,收益5.86刀。
主要是UVXY和UPST亏的较多!
其中UPST就是连涨2根bar的情况,所以成本略高。
UVXY则是均线缠绕,导致TradingView和机器人的计算结果不一致,之后多积累一些case,看看此类情况该如何过滤掉。
第2天实盘:10月7日,周四
共交易43只股票(表太长,这里就不列出了),最终亏损37刀。
因信号较多,所以机器人额度从1w增加到1.5w。
机器人自己记录的情况是亏损31刀,差异的原因是:机器人记录的是市价,而且一般延迟10秒左右,人工统计的是实际成交价(市价单),市价单在金额上不是那么优惠。
反思和改进:
bug1:
未走完的bar产生的信号,如最后一根bar(15:30-16:00)产生的信号:5单里亏损4单。
而且这是之前就已经改进的点,现在又出现!明显有bug!
检查后,发现是上次修改(盘中无限循环跑→每根bar结束时跑)时没注意到的一个连锁反应。
更正后,还优化了显示问题(排序和序号)。
止损共22单,其中18单(亏损37刀)都存在bug1。
止盈共10单,其中2单存在bug1。
尾盘平仓共11单,其中5单存在bug1。
bug2:
有计算误差的信号(K线有误),即python机器人计算结果与TradingView差异较大的信号。
比如:CLF,TradingView认为13:30开始的bar才是long1信号(起涨点做多),但机器人认为是前一根(13:00-13:30),即机器人认为前一根是阳线 且 出头。
阳线算错了还能理解,因为这根bar(13:00-13:30)是十字星,开盘价和收盘价都是20.82(TradingView);富途的结果更精准:开盘价=20.820、收盘价=20.818,是阴线;机器人的结果是:开盘价=20.81、收盘价=20.84,是阳线。
出头算错则误差太大!因为前一根bar(12:30-13:00)的高点是20.86(TradingView)、20.859(富途),机器人结果是20.78!难道是行情机器人(无限循环查询市价)有误?查看其记录的价格csv文件,发现这一段时间的最高点是20.855(12:40:49和12:40:55两次记录)。
本地逐行代码地跑了一遍,问题也不能复现,所以,要么是当时的市价csv有问题,要么是当时的python计算有问题。
这种最基础的计算出现如此大的误差,不能原谅!但现在找不到原因,也只好暂时作罢。如果之后发现此类问题负面影响太大,那可以考虑将行情源从TD查询换为TD订阅,或者换为富途(曾短暂使用,放弃原因是太贵而且有订阅数量限制)。
无bug1的止损单共4单,其中3单存在bug2。
此类case还有:
TWTR 10:30-11:00,收盘价=63.645,正确值=63.93(TradingView)。
无bug1和bug2的止损单,仅1单:MDY。
另有一处可以改进的地方:
既然是日内交易,那么以昨天的低点为止损线就不太合适了,尤其是跳空高开的时候,如GS: