威廉指标-WR,也是业内大名鼎鼎的一个辅助性指标,还是先说明,这个指标我也不熟悉,你们也许该鄙视我了,不熟悉还写什么的。我只能说的是,我解读的是代码,不是解读指标,百度里关于各指标,已经都有明确的描述了。解读代码的本意呢,是因为我以前打算做程序化的时候,一直想找相关的解读而没有找到,编码大神又觉得这些没什么好写的,那时我就苦恼着从头一点点的啃c++语言,所以在这里也只是解读一下,告诉大家怎么看一个代码。当然,聪明的朋友,看了这些,要能写出自己的交易程序那就牛逼了。
好了,废话也不说了,直接说代码吧,威廉指标TB系统里给它写了三个函数,如下。
第一个求最高函数Highest,代码如下:
Params
NumericSeries Price(0);//声明序列参数Price,赋值0.//
Numeric Length(5); //声明参数Length,赋值5。//
Vars
Numeric HighestValue;//声明变量HighestValue.//
Numeric i;//声明变量 i。//
Begin
HighestValue = Price;//变量HighestValue的值等于价格。//
for i=1 to Length - 1//循环语句,变量i的值从1循环到参数Length-1,循环执行花括号里的语句程序。//
{
If(Price[i] > HighestValue)//假如Price[ i ]大于变量HighestValue,其实这当前价格是一个中间值,作用是为了求前1,2,3,4数位的价格哪个最大。//
HighestValue = Price[i];//可以看到,假如Price[1]的值大于当前价,那么就把Price[1]的值赋予给HighestValue,再把Price[1]跟Price[2]对比,循环到Price[4]为止。//
}
Return HighestValue;//根据对比的这5根k线的价格,把最大值返回给主函数。//
End
第二个求最低函数Lowest,代码如下:(这个解读意思同上,就是把对比5根k线的最低价)
Params
NumericSeries Price(0);
Numeric Length(5);
Vars
Numeric LowestValue;
Numeric i;
Begin
LowestValue = Price;
for i=1 to Length - 1
{
If(Price[i] < LowestValue)
LowestValue = Price[i];
}
Return LowestValue;
End
第三个就是求威廉指标函数PercentR,算法很简单,就是N日内最高价与当日收盘价的差,除以N日内最高价与最低价的差,结果放大100倍。代码如下:
Params
Numeric Length(10);//声明参数Length,赋值为10.记住了,这个初值10是可以变的。//
Vars
Numeric HH;//声明变量名为HH。//
Numeric Divisor;//声明变量名为Divisor。//
Numeric PRValue;//声明变量名为PRValue。//
Begin
HH = Highest(High, Length);//变量HH值等于,调用函数Highest,求出10周期内的最高价。//
Divisor = HH - Lowest(Low, Length);//变量Divisor值等于,10周期内的最高价减去最低价。//
If (Divisor <> 0 )//假如变量Divisor不等于0.//
PRValue = 100 - ( ( HH - Close ) / Divisor ) * 100;//看着都明白,直白翻译了,变量PRValue值 = 100 - ((10周期内最高价-当前收盘价)/变量Divisor值)* 100//
else//假如变量Divisor等于0.//
PRValue = Divisor;//变量PRValue等于0了//
Return PRValue;//把变量PRValue的值返回给主函数,其实所谓主函数就是编写的代码里直接调用出来。//
End
TB系统里真正显示在k线图里的威廉函数代码很简洁的,如下:
Params
Numeric Length(5);//声明参数Length,赋值5.//
Numeric OverSold(20) ;//声明参数OverSold,赋值20.//
Numeric OverBought(80) ;声明参数OverBought,赋值80.//
Vars
Numeric WRValue;//声明变量WRValue。//
Begin
WRValue = PercentR(Length);//变量WRValue值,其实就是把参数5带回函数PercentR里重新求一遍,再把得到的值返回来给WRValue。//
PlotNumeric("WR",WRValue);//画线WR,替代WRValue。//
PlotNumeric("超买",OverBought);//画线超买,就是初值80.//
PlotNumeric("超卖",OverSold);//画线超卖,就是初值20.//
End
这代码看明白了,怎么求值威廉指标也清楚了,我们可以做个程序化交易代码出来。买卖规则很简单,也就是个跟RSI指标共振罢了。即同步穿过50中间值,买入;同步跌破50中间值,卖出。固定止损30,止盈分50,与80两级。代码及测试结果如下:
Params
Numeric Length1(10);
Numeric Length(14) ;
Numeric TrailingStart1(50); // 跟踪止盈启动设置1//
Numeric TrailingStart2(80); // 跟踪止盈启动设置2//
Numeric TrailingStop1(30); // 跟踪止盈设置1//
Numeric TrailingStop2(20); // 跟踪止盈设置2//
Numeric StopLossSet(30); //固定止损30个点//
Vars
Numeric HH;
Numeric Divisor;
NumericSeries PRValue;
NumericSeries NetChgAvg( 0 );
NumericSeries TotChgAvg( 0 );
Numeric SF( 0 );
Numeric Change( 0 );
Numeric ChgRatio( 0 ) ;
NumericSeries RSIValue;
NumericSeries HighestAfterEntry;
NumericSeries LowestAfterEntry;
Numeric MinPoint;
Numeric MyEntryPrice;
Numeric myprice;
Numeric myexitprice;
Begin
//计算WR指标//
HH = Highest(High, Length1);
Divisor = HH - Lowest(Low, Length1);
If (Divisor <> 0 )
PRValue = 100 - ( ( HH - Close ) / Divisor ) * 100;
else
PRValue = Divisor;
//计算RSI指标//
If(CurrentBar <= Length - 1)
{
NetChgAvg = ( Close - Close[Length] ) / Length ;
TotChgAvg = Average( Abs( Close - Close[1] ), Length ) ;
}Else
{
SF = 1/Length;
Change = Close - Close[1] ;
NetChgAvg = NetChgAvg[1] + SF * ( Change - NetChgAvg[1] ) ;
TotChgAvg = TotChgAvg[1] + SF * ( Abs( Change ) - TotChgAvg[1] ) ;
}
If( TotChgAvg <> 0 )
{
ChgRatio = NetChgAvg / TotChgAvg;
}else
{
ChgRatio = 0 ;
}
RSIValue = 50 * ( ChgRatio + 1 );
If(!CallAuctionFilter()) Return;// 集合竞价和小节休息过滤
If(MarketPosition <>1 && PRValue[1] >= 50 And RSIValue[1] >= 50)
{
Buy(1,Open);
}
If(MarketPosition <>-1 && PRValue[1] <= 50 And RSIValue[1] <= 50)
{
SellShort(1,Open);
}
If(BarsSinceentry == 0)
{
HighestAfterEntry = Close;
LowestAfterEntry = Close;
If(MarketPosition <> 0)
{
HighestAfterEntry = Max(HighestAfterEntry,AvgEntryPrice); // 开仓的Bar,将开仓价和当时的收盘价的较大值保留到HighestAfterEntry//
LowestAfterEntry = Min(LowestAfterEntry,AvgEntryPrice); // 开仓的Bar,将开仓价和当时的收盘价的较小值保留到LowestAfterEntry//
}
}else
{
HighestAfterEntry = Max(HighestAfterEntry,High); // 记录下当前Bar的最高点,用于下一个Bar的跟踪止损判断//
LowestAfterEntry = Min(LowestAfterEntry,Low); // 记录下当前Bar的最低点,用于下一个Bar的跟踪止损判断//
}
Commentary("HighestAfterEntry="+Text(HighestAfterEntry));
Commentary("LowestAfterEntry="+Text(LowestAfterEntry));
Commentary("MyEntryPrice="+Text(MyEntryPrice));
MinPoint = MinMove*PriceScale;
MyEntryPrice = AvgEntryPrice;
If(MarketPosition==1) // 有多仓的情况//
{
If(HighestAfterEntry[1] >= MyEntryPrice + TrailingStart2*MinPoint) // 第二级跟踪止损的条件表达式//
{
If(Low <= HighestAfterEntry[1] - TrailingStop2*MinPoint)
{
MyExitPrice = HighestAfterEntry[1] - TrailingStop2*MinPoint;
Sell(0,MyExitPrice);
}
}else if(HighestAfterEntry[1] >= MyEntryPrice + TrailingStart1*MinPoint)// 第一级跟踪止损的条件表达式//
{
If(Low <= HighestAfterEntry[1] - TrailingStop1*MinPoint)
{
MyExitPrice = HighestAfterEntry[1] - TrailingStop1*MinPoint ;
Sell(0,MyExitPrice);
}
}else if(Low <= MyEntryPrice - StopLossSet*MinPoint)//可以在这里写上初始的止损处理//
{
MyExitPrice = MyEntryPrice - StopLossSet*MinPoint;
Sell(0,MyExitPrice);
}
}else if(MarketPosition==-1) // 有空仓的情况//
{
If(LowestAfterEntry[1] <= MyEntryPrice - TrailingStart2*MinPoint) // 第二级跟踪止损的条件表达式//
{
If(High >= LowestAfterEntry[1] + TrailingStop2*MinPoint)
{
MyExitPrice = LowestAfterEntry[1] + TrailingStop2*MinPoint;
BuyToCover(0,MyExitPrice);
}
}else if(LowestAfterEntry[1] <= MyEntryPrice - TrailingStart1*MinPoint)// 第一级跟踪止损的条件表达式//
{
If(High >= LowestAfterEntry[1] + TrailingStop1*MinPoint)
{
MyExitPrice = LowestAfterEntry[1] + TrailingStop1*MinPoint;
BuyToCover(0,MyExitPrice);
}
}else If(High >= MyEntryPrice + StopLossSet*MinPoint)//可以在这里写上初始的止损处理//
{
MyExitPrice = MyEntryPrice + StopLossSet*MinPoint;
BuyToCover(0,MyExitPrice);
}
}
End
看着结果还不错吧,但是它的交易频率太高了点,我也不知道具体实盘结果如何,这个程序化也是今天写这篇文章,顺带就写出来,测试一下而已,有兴趣的朋友可以自己观察实盘看看的。对了,这个威廉除了可以跟RSI指标一起用以外,还可以跟别的,比如移动均线啊,或者布林带啊等等。也是把代码复制进去,修改一下买卖的指令就可以了,结果如何,大家有兴趣的可以试试的。