趋势策略小试牛刀,海龟交易体系的小白构建
暑假在家发现了这个挖金矿的地方,狠狠泡了些日子,津(hun)津(hun)有(yu)味(shui)地阅读API文档,一步步把海龟的轮廓构建起来。
由于帖子长度控制有限,,我将内容分两个帖子写
这个帖子的框架:
所用策略平台:ricequant,米筐科技的策略平台(www.ricequant.com),ps个人觉得不错,建议大家去用用试试。
选择实现海龟策略也是有原因的,海龟交易法则不是仅仅停留在指标系统的阶段,准确说,它已经正真意义上的形成了交易系统的雏形,它涵盖了交易的各个方面,没有给交易员留下主观想象决策的余地,这正好使得程序化操作该系统的优势得到发挥。这一步步敲击代码的过程中收获还是不少,今天我也来放上自己的思考和代码与大家伙分享。
首先,我们从趋势策略说起......
在国内A股浓厚的追涨杀跌气氛中,第一感觉趋势追随策略简单粗暴有效,不过我觉得,看待一个策略就像看待一个人一段历史一样,时间拉长,作出评价才更加客观。
我们先来看看API中自带的基于趋势指标MACD的策略,关于MACD的介绍可以戳Technical Analysis from A to Z,A Primer On The MACD,MACD Histogram Helps Determine Trend Changes,以及计算公式。为消除选股因素影响,交易标的使用日指数数据CSI300.INDX。为和后续策略对比,回测时间统一设定为20050710-20150710这十年时间。
MacdStrategy Code:
[url=]Clone[/url]public class MACDStrategy implements IHStrategy { Core taLibCore;
static double delta =
0; @Override public void init(IHInformer informer, IHInitializers initializers) {
int shortPeriod =
12;
int longPeriod =
26;
int smoothingPeriod =
9;
int observePeriod =
100;
double[] macdOut =
new double[observePeriod];
double[] macdSignal =
new double[observePeriod];
double[] macdHist =
new double[observePeriod]; MInteger macdBegin =
new MInteger(); MInteger macdLength =
new MInteger(); taLibCore =
new Core(); String stockId =
"CSI300.INDX"; initializers.instruments((instruments) -> instruments.add(stockId)); initializers.events().statistics((stats, info, trans) -> {
double[] closePxObservePeriodIn = stats.
get(stockId).history(observePeriod, HPeriod.Day).getClosingPrice(); RetCode retCode = taLibCore .macd(
0, observePeriod -
1, closePxObservePeriodIn, shortPeriod, longPeriod, smoothingPeriod, macdBegin, macdLength, macdOut, macdSignal, macdHist);
if (retCode != RetCode.Success) throw new RuntimeException("TALib was unable to process data");
double previousDelta = delta; delta = macdOut[macdLength.
value -
1] - macdSignal[macdLength.
value -
1];
double curPosition = info.position(stockId).getNonClosedTradeQuantity();
double quantity = info.portfolio().getAvailableCash() / stats.
get(stockId).getLastPrice();
if ((previousDelta >
0) && delta <
0) {
if (curPosition >
0) { trans.sell(stockId).shares(curPosition).commit(); } } else if ((previousDelta < 0) && delta > 0) { trans.buy(stockId).shares(quantity).commit(); } }); }}
回策结果:
嗯...好像并没有想象那么好,平时看交易软件上的MACD觉得靠谱得不得了,不过这样看也没有那么神呐,最大回撤快五十了额,我是不敢把银子交给它...睡不着觉啊,不过夏普0.80,十年时间,也不容易......也算差强人意了。
好了,下面切换到我们的正题:海龟交易法则。听我一本正经地娓娓道来:
海龟交易法则背景海龟交易的创始人是七八十年代著名的期货投机商Richard Dennis,他相信优秀的交易员是后天培养而非天生的。他在1983年12月招聘了23名新人,昵称为海龟,并对这些交易员进行了一个趋势跟踪交易策略培训。随后给予每个新人100万美元的初始资金。经5年的运作,大部分“海龟”的业绩非常惊人,其中最好的业绩达到1.72亿美元。N年后海龟交易法则公布于世,我们才有幸看到曾名噪一时的海龟交易法则全貌。(画外音:能够开发出领先时代的交易模型,收益是多么诱人!)
海龟交易法则内容海龟交易法则的原版书籍可以戳Turtle.
这里先画个简单的思维导图表示下海龟交易法则的基本框架:

下面一个个具体来说:
市场:海龟们都是期货交易者,海龟们只选择有一定交易量流动性高的市场。这里我选择日指数数据CSI300.INDX,一方面是为了更好与基准比较,另一方面也是因为该标的可以不用担心流动性的问题。
头寸规模:头寸规模是海龟交易系统最重要的部分之一。头寸规模是海龟交易系统最重要的部分之一。头寸规模是海龟交易系统最重要的部分之一。
海龟交易法则根据一个市场的绝对波动幅度来调整头寸规模,也就是将头寸的绝对波动幅度进行了标准化。比如,投资标的的价值波动性较强时,可以减少持有量,相反,当它的价值波动性较弱时候,可以增加持有量。总而言之,市场的波动性与头寸规模可以相互抵消。
海龟用一个被称为N的概念来表示某个市场根本的波动性,它表示单个交易日某个特定市场所造成的价格波动的平均范围,它同时也涵盖了开盘价的缺口。其实这个所谓的N,就是我们平常所熟悉的ATR,关于ATR的介绍,可以戳AVERAGE TRUE RANGE.
以下为计算公式:
TR=Max(H-L,H-PDC,PDC-L)
其中:
TR=真实波幅
H=当日最高价
L=当日最低价
PDC=前一日收盘价
N(即ATR)的计算公式如下(其实就是前面计算所得TR的20日移动平均):
N=(19*PDN+TR)/20
其中:
PDN=前一日N值
TR=当日的真实波动幅度
有了N之后,下一步可以计算绝对波动幅度,也就是用根本的市场价格波动性(用N值定义)表示的价值量波动性。
绝对波动幅度=N*合约每一点所代表的价值
最后,海龟按照我们所称的单位(Units)建立头寸。使1N代表帐户净值的1%。 波幅调整后的头寸单位为:
头寸规模单位=账户的1%/市场的绝对波动幅度
可以看出,使用N作为市场波动标准化的度量并以此作为开仓量及持仓量的依据,其背后的资金管理含义是,即便当日投资标的跌幅达到N(ATR)的水平,当日的损失都能控制在1%的总资产水平内。 即便当日投资标的跌幅达到N(ATR)的水平,当日的损失都能控制在1%的总资产水平内。 即便当日投资标的跌幅达到N(ATR)的水平,当日的损失都能控制在1%的总资产水平内。
以书中给的参考为例:
2003年3月份民用燃料油合约
日期 | 最高价 | 最低价| 收盘价| 真实波幅| N值
-------- | ---
2002/12/2| 0.7375| 0.7227| 0.7359| 0.0148| 0.0134
2002/12/3|0.7447| 0.7310| 0.7389| 0.0137| 0.0134
2002/12/4 |0.7420|0.7140| 0.7162| 0.0280| 0.0141
-------- | ---
根据12月4日的N值0.0141计算头寸规模如下:
N=0.0141
账户规模=1000000美元
每一点的价值=42000美元
头寸单位规模=0.011000000/0.014142000=16.88
舍去小数,得16份合约。
另外,海龟被限制在任何时间持仓的单位(Units)数目,在证券市场这种单一市场中,最多持仓的单位数设为4个单位,且海龟一般每周一计算一次N用于更新单位(Units)大小。
入市:海龟的入市规则有两个系统,我们可以根据自己的意愿决定将净值配置在何种系统上。
由于我的回测周期较长,我选择了系统二,即以55日突破为基础的较简单的长线系统。
追踪海龟交易系统不是一有突破信号就全仓介入,而是根据最新市场价格变化进行逐步建仓。
海龟在价格突破时只建立一个单位的头寸,在建立头寸后根据前面指令的实际成交价为基础以每突破0.5N的间隔进行加仓。
例如:
黄金:N=2.5
55日突破=310
增加的第一个单位310.00
第二个单位310.00+1/2个2.5即311.25
第三个单位311.25+1/2个2.5即312.50
第四个单位312.50+1/2个2.5即313.75
海龟被告知在接受入市信号时要非常连续,因为一年中的大部分利润可能仅仅来自两三次大赢利。
止损对大多数人来说,始终抱着亏损的交易终究会反转的愿望比干脆退出亏损头寸并承认交易失败要容易得多。长期看,不会止损的交易是不会成功的。在你建立头寸之前,你需要预先确定退出的点位。如果市场波动触及你的价位,你就必须每一次毫无例外的退出。在这一立场上摇摆不定最终会导致灾难。(画外音:前段时间大家应该体会比较深刻吧。)
止损标准
海龟以头寸风险为基础设置止损,任何一笔交易不能出现2%以上的风险,因为价格波动1N表示1%的账户净值,容许风险为2%的最大止损就是价格波动2N,为了保证全部头寸的风险最小,如果另外增加了单位,前面单位的止损需提高0.5N。
例如:
原油:N=1.255 日突破=28.30
第一单位 28.30 25.90
离市艰难的离市
对于大多数交易员,海龟离市规则是系统法则中唯一最难的部分。等待10或20新低出现通常意味着眼睁睁瞅着20%,40%甚至100%的利润化为泡影。
海龟交易法则对于系统一系统二有着不同的离市标准:
系统一
离市对于多头头寸为10日最低价,对于空头头寸为10日最高价。如果价格波动于头寸背离至10日突破头寸中所有单位都会退出系统二
离市对于多头头寸为20日最低价,对于空头头寸为20日最高价,如果价格波动与头寸背离至20日突破头寸中所有单位都会退出
海龟入市时一般不会设置离市止损价,但会在日间盯着价格,一旦价格穿过离市突破价,就开始打电话下离市
指令。
规则告一段落
以上就是海龟交易系统的全套法则内容,法则的每一部分及各部分的关联构成了一个交易系统,下面,我们一步步实现......由于帖子长度原因。。。请看【原创】【量化策略】海龟交易体系的小白构建(二)之交易实现