这是一个期货爱好者的个人分享,不是专业程序员,各位编码大神看了请不要见笑。
好了话不多说,我直接用求平均值AverageFC代码附上,一一解释说明。
Params
NumericSeries Price(1);
Numeric Length(10);
Vars
Numeric AvgValue;
Begin
AvgValue = Summation(Price, Length) / Length;
Return AvgValue;
End
解释如下:
Params /*参数声明,直白的解释就是起个名字,如张三、李四等,这里都是用英文表达而已*/
Numeric Length(10); /*Numeric数据类型,TB系统分三大类型,想了解的,可细查。Length(10), Length就是说给起的这么个名字,(10)这个数据统计10个周期,也就是10 根 k 线,它的起点从第一根开始算*/
NumericSeries Price(1); /*NumericSeries数据类型的序列变量,跟Numeric区别,我一般这么辨认 的,跟价格相关的就用NumericSeries,如开盘价、收盘价或价格等;其他的直 接用Numeric。Price(1)也就是名字为价格,给它的初始值为1。*/
Vars /*变量声明,怎么说呢,用数学上y=x+1来解说就是,TB系统要使用变量y,先给它做个声明吧*/
Numeric AvgValue; /*Numeric数据类型,AvgValue就是我们说的变量,先给它来做个声明,接下来 才能使用,要不然你在程序里随便写别的英文,没给它声明,系统没法知道这 个英文要表达什么意思啊。*/
Begin /*正文编程的开始了。*/
AvgValue = Summation(Price, Length) / Length; /*其实我要写成这样 AvgValue=(Price1+Price2+Price3+......+Price9+Price10)/Length, 大家看了该理解什么意思了吧。Summation(Price,Length)替代了 那逐步的价格相加,求和函数Summation这个是已经编好的函数库,可 直接调用,按它的格式要求写能求出相应和。所以这段代码整体意思: 求10根 k线的平均价格。*/
Return AvgValue; /*Return返回函数,没什么可说的,语句意思就是:算完一遍10根k线的平均值,返 回AvgValue再重新求第二遍,直到最新的k线价格结束。*/
End /*结束标志,告诉TB系统,你编写的程序好了,可以终止了。*/
了解了怎么函数AverageFC求平均值,那么接下来看我们经常用的双均线移动平均线交易系统的源代码如何直接调用它的。
Params
Numeric FastLength(5); /*声明参数FastLength初始值为5个周期数*/
Numeric SlowLength(20); /*声明参数SlowLength初始值为20个周期数*/
Vars
NumericSeries AvgValue1; /*声明序列变量做个声明为AvgValue1,为什么用的是NumericSeries, 正文编程中可知道这个是求价格的平均值,跟价格相关,那就直接用它了*/
NumericSeries AvgValue2; /*同上意思*/
Begin
AvgValue1 = AverageFC(Close,FastLength); /*这个就是直接调用了函数AverageFC,意思为: AvgValue1的值等于5根k线收盘价的平均价格。*/
AvgValue2 = AverageFC(Close,SlowLength); /*AvgValue2的值等于20根收盘价的平均价格*/
PlotNumeric("MA1",AvgValue1); /*函数PlotNumeric意思在k线图中显现出来,字符串"MA1",其实 可以直接写别的英文或用原来AvgValue1都可以,只是这边为了形 成统一习惯罢了。则这语句意思:线MA1代表了AvgValue1。*/
PlotNumeric("MA2",AvgValue2); /*线MA2代表AvgValue2。*/
If(!CallAuctionFilter()) Return; /*在公式应用的开始位置添加该行代码,可以对集合竞价和小结开始的 行情进行过滤,防止无效的发单操作。所以意思就是:集合竞价和小节 休息过滤掉。*/
If(MarketPosition <>1 && AvgValue1[1] > AvgValue2[1]) /*MarketPosition当前持仓状态;&&意 思为和,也可直接用and替代;<>意思 是不等于,这里MarketPosition后的 (1,0,-1)意思各为1为多单,0为没 有仓位,-1为空单;AvgValue1[1]这个 中括号[1]意思是前一个AvgValue1平均 价格。这语句整体意思为:假如当前没有 持多单,并且均线AvgValue1[1]大于 AvgValue2[1]。*/
{
Buy(1,Open); /*开多单一般直接用Buy,意思为以当前k线的开盘价,开仓买入1手。*/
}
If(MarketPosition <>-1 && AvgValue1[1] < AvgValue2[1]) /*假如当前没有持空单,并且均线 AvgValue1[1]小于AvgValue2[1]。*/
{
SellShort(1,Open); /*开空单一般用SellShort,意思为以当前K线的开盘价,开仓卖出1手。*/
}
End
根据这源代码正常测试公式,不同周期,得到收益差距很大,你会发现周期时间越大,它的K线波多越剧烈,得到的结果收益跟亏损不怎么理想的。
根据测试我一般建议关注以下几个点:
1、开仓点位,这很重要,你是以开盘价、收盘价或则指定价格开仓,在历史K线中测试时,结果可能很理想,但实盘能否如此理想,你得在开盘期间确认一下。
2、盈亏比,不管均线系统,还是别的系统,一般都是以小亏损来换取大盈利的,这种要求盈亏比3:1,成功率25%左右,最后得到的结果才有可能是正的。(当然高成功率也可以,但这种人很少,而且这种系统我也暂时没见过,我看到的基本都是小亏大盈的系统,成功率最高的也就是45%-50%)
3、参数优化,上面的代码参数是5跟20,你要是觉得这参数不符合你心意,那你可以照你经验来修改。我常用的方法是测试所有的品种,各周期不同也都优化一遍,最后统计出一个相对符合数据的参数(不是符合我自己心意的)。
4、交易频率,像上面的源代码,交易频率很快,基本就是平仓的同时,就反手开新仓的。这频繁的交易,可能跟你交易理念也不相符,比如正在上涨趋势,只是因为均线参数过小,它有交叉了,系统就自动显示平仓,反手卖出。要怎么解决这个问题呢?只要在系统中添加新一条更大的均线限制就行。
好了,在结束前,我就附上一个修改后的源代码,有空你们自己测试一下,这均线还是很好的,记得这是针对3、5分钟周期的k线图。
Params
Numeric FastLength(5);
Numeric SlowLength(20);
Numeric DslowLength(200);
Vars
NumericSeries AvgValue1;
NumericSeries AvgValue2;
NumericSeries AvgValue3;
Begin
AvgValue1 = AverageFC(Close,FastLength);
AvgValue2 = AverageFC(Close,SlowLength);
AvgValue3 = AverageFC(Close,DslowLength);
PlotNumeric("MA1",AvgValue1);
PlotNumeric("MA2",AvgValue2);
PlotNumeric("MA3",AvgValue3);
// 集合竞价和小节休息过滤
If(!CallAuctionFilter()) Return;
If(MarketPosition <>1 && AvgValue1[1] > AvgValue2[1] && Close > AvgValue3[1])
{
Buy(1,Open);
}
If(MarketPosition ==1 && AvgValue1[1] < AvgValue2[1])
{
Sell(1,Open);
}
If(MarketPosition <>-1 && AvgValue1[1] < AvgValue2[1] && Close < AvgValue3[1])
{
SellShort(1,Open);
}
If(MarketPosition ==-1 && AvgValue1[1] > AvgValue2[1])
{
BuyToCover(1,open);
}
End