策略说明:
通过计算市场的潮汐指数,把市场划分为震荡和趋势两种走势;震荡市中
采用开盘区间突破进场;趋势市中采用布林通道突破进场。
系统要素:
1、潮汐指数
2、关键价格
3、布林通道
4、真实波幅
5、出场均线
入场条件:
1、震荡市中采用开盘区间突破进场
2、趋势市中采用布林通道突破进场
出场条件:
1、震荡市时进场单的出场为反手信号和ATR保护性止损
2、趋势市时进场单的出场为反手信号和均线出场
做多代码及解读如下:
Params
Numeric swingTrendSwitch(20); // 声明数值参数swingTrendSwitch,初值20,即潮汐指数小于此值为震荡市,否则为趋势市。//
Numeric swingPrcnt1(0.50); // 声明数值参数swingPrcnt1,初值0.5,即震荡市开仓参数。//
Numeric swingPrcnt2(0.75); // 声明数值参数swingPrcnt2,初值0.75,即震荡市开仓参数。//
Numeric atrLength(10); //声明数值参数atrLength,初值10,即真实波幅参数。//
Numeric bollingerLengths(50); // 声明数值参数bollingerLengths,初值50,即布林通道参数。//
Numeric numStdDevs(2); //声明数值参数numStdDevs,即布林通道参数。//
Numeric trendLiqLength(50); // 声明数值参数trendLiqLength,初值50,趋势市时进场单的出场均线参数。//
Numeric Lots(0); // 声明数值参数Lots,初值0,即交易手数。//
Vars
NumericSeries cmiVal(0); //声明数值序列变量cmiVal,初值0,即潮汐指数。//
BoolSeries buyEasierDay(False); // 声明布尔型序列变量buyEasierDay,初值为假,宜买市。//
BoolSeries sellEasierDay(False); //声明布尔型序列变量sellEasierDay,初值为假, 宜卖市。//
NumericSeries myATR(0); // 声明数值序列变量myATR,初值为0,即真实波幅。//
NumericSeries MidLine(0); // 声明数值序列变量MidLine,初值0,即布林通道中轨。//
Numeric Band(0); //声明数值变量Band,初值0.//
NumericSeries upBand(0); // 声明数值序列变量upBand,初值0,即布林通道上轨。//
NumericSeries dnBand(0); //声明数值序列变量dnBand,初值0, 布林通道下轨。//
NumericSeries trendLokBuy(0);//声明数值序列变量trendLokBuy,初值0.//
NumericSeries trendLokSell(0);//声明数值序列变量trendLokSell,初值0.//
NumericSeries keyOfDay(0); // 声明数值序列变量keyOfDay,初值0,即关键价格。//
NumericSeries swingBuyPt(0); //声明数值序列变量swingBuypt,初值0,即 震荡市的买触发价格。//
NumericSeries swingSellPt(0); // 声明数值序列变量swingSellpt,初值0,震荡市的卖触发价格//
NumericSeries trendBuyPt(0); //声明数值序列变量trendBuypt,初值0,即 趋势市的买触发价格。//
NumericSeries trendSellPt(0); // 声明数值序列变量trendSellpt,初值0,即趋势市的卖触发价格。//
NumericSeries swingProtStop(0); //声明数值序列变量swingProtStop,初值0, 震荡市时进场单的出场触发价格//
NumericSeries trendProtStop(0); // 声明数值序列变量trendProtStop,初值0,即趋势市时进场单的出场触发价格。//
BoolSeries swingEntry(False); //声明布尔型序列变量swingEntry,初值为假,即 震荡市时进场标识。//
Begin
If(!CallAuctionFilter()) Return;// 集合竞价和小节休息过滤。//
// 计算潮汐指数用以区分震荡市与趋势市。//
cmiVal = Abs(Close - Close[29])/(Highest(High,30) - Lowest(Low,30))*100; //照顺序来看吧,第一个绝对值函数Abs,即当前收盘价减去前第29个收盘价,取绝对值;再看求最高价函数Highest,即求30周期的最高价;同理,最低函数Lowest,求30周期的最低价。最后代入公式求解,即得cmiVal值。//
trendLokBuy = Average(Low,3);//求3周期内最低价均值。//
trendLokSell= Average(High,3);//求3周期内最高价均值。//
// 关键价格。//
keyOfDay = (High + Low + Close)/3; //其实就是3个价格的平均值。//
// 震荡市中收盘价大于关键价格为宜卖市,否则为宜买市。//
buyEasierDay = False;//赋值为假。//
sellEasierDay = False;//赋值为假。//
If(Close[1] > keyOfDay[1]) sellEasierDay = True;//假如前一个收盘价大于前一个关键价,则变量sellEasierDay赋值为真。//
If(Close[1] <= keyOfDay[1]) buyEasierDay = True;//假如前一个收盘价小于等于前一个关键价,则变量buyEasierDay赋值为真。//
// 计算震荡市的进场价格//
myATR = AvgTrueRange(atrLength);//求10周期的真实波动值。//
If(buyEasierDay == True)//假如变量buyEasierDay等于真的。//
{
swingBuyPt = Open + swingPrcnt1*myATR[1];//代入相应数值即可。//
swingSellPt = Open - swingPrcnt2*myATR[1];//同理,代入相应数值。//
}
If(sellEasierDay == True)//假如变量sellEasierDay等于真。//
{
swingBuyPt = Open + swingPrcnt2*myATR[1];//代入相应数值了。//
swingSellPt = Open - swingPrcnt1*myATR[1];//同理的,其实主要看的就是系数。//
}
swingBuyPt = Max(swingBuyPt,trendLokBuy[1]);//比较变量swingBuyPt与前一个变量trendLokBuy值,取较大值。//
swingSellPt = Min(swingSellPt,trendLokSell[1]); //比较swingSellPt值与前一个trendLokSell值,取较小值。//
// 计算趋势市的进场价格,即布林带系统。//
MidLine = AverageFC(Close,bollingerLengths); //50周期的收盘价均值。//
Band = StandardDev(Close,bollingerLengths,2); //标准差求值,可返回之前解读的布林线看具体函数代码。//
upBand = MidLine + numStdDevs*Band;//上轨道计算公式。//
dnBand = MidLine - numStdDevs*Band; //下轨道计算公式。//
trendBuyPt = upBand;//把上轨道赋值给变量trendBuyPt值。//
trendSellPt = dnBand;//把下轨道赋值给变量trendSellPt值。//
// 震荡市。//
If(cmiVal[1] < swingTrendSwitch) //假如前一个变量cmiVal值小于变量swingTrendSwitch值。//
{
If(MarketPosition != 1 And High >= swingBuyPt) //假如当前没有持多单,且最高价大于等于变量swingBuyPt值。//
{
Buy(Lots,Max(Open,swingBuyPt));//开仓买入。//
swingEntry = True;//变量swingEntry赋值为真。//
}
If(MarketPosition == 1 And BarsSinceEntry >= 1 And Low <= swingSellPt) //假如当前持有多单,且建仓数位大于等于1,且最低价小于等于变量swingSellPt值。//
{
Sell(0,Min(Open,swingSellPt));//平仓。//
swingEntry = False;//变量sweingEntry赋值为假。//
}
}
swingProtStop = 3*myATR;//止损价swingProtStop = 3 *变量myATR值。//
trendProtStop = Average(Close,trendLiqLength); //50周期收盘价均值。//
// 趋势市判断。//
If(cmiVal[1] >= swingTrendSwitch) //假如前一cmiVal值大于等于变量swingTrendSwitch值。//
{
// 震荡市时进场单在趋势市的出场。//
If(swingEntry == True) //假如变量swingEntry等于真。//
{
If(MarketPosition == 1 And BarsSinceEntry >= 1 And Low <= (EntryPrice - swingProtStop[1])) //假如当前持有多单,且建仓数位大于等于1,且最低价小于等于进场价减去前一止损价。//
{
Sell(0,Min(Open,EntryPrice - swingProtStop[1])); //平仓。//
swingEntry = False;//变量swingEntry赋值为假。//
}
}
// 趋势市时进出场 。//
If(swingEntry == False) //假如变量swingEntry等于假。//
{
If(MarketPosition != 1 And BarsSinceExit >= 1 And High >= trendBuyPt[1]) //假如当前没有持仓,且出场数位大于等于1,且最高价大于等于前一变量trendBuyPt值。//
{
Buy(Lots,Max(Open,trendBuyPt[1]));//开仓买入。//
}
If(MarketPosition == 1 And BarsSinceEntry >= 1 And Low <= Max(trendSellPt[1],trendProtStop[1])) //假如持有多单,且建仓数位大于等于1,且最低价小于等于两出场价中的较大值。//
{
Sell(0,Min(Open,Max(trendSellPt[1],trendProtStop[1])));//平仓,这里先看比较max值,再比较min值,最后以较小价为平仓价。//
}
}
}
End
做空代码及结果如下:
Params
Numeric swingTrendSwitch(20);
Numeric swingPrcnt1(0.50);
Numeric swingPrcnt2(0.75);
Numeric atrLength(10);
Numeric bollingerLengths(50);
Numeric numStdDevs(2);
Numeric trendLiqLength(50);
Numeric Lots(0);
Vars
NumericSeries cmiVal(0);
BoolSeries buyEasierDay(False);
BoolSeries sellEasierDay(False);
NumericSeries myATR(0);
NumericSeries MidLine(0);
Numeric Band(0);
NumericSeries upBand(0);
NumericSeries dnBand(0);
NumericSeries trendLokBuy(0);
NumericSeries trendLokSell(0);
NumericSeries keyOfDay(0);
NumericSeries swingBuyPt(0);
NumericSeries swingSellPt(0);
NumericSeries trendBuyPt(0);
NumericSeries trendSellPt(0);
NumericSeries swingProtStop(0);
NumericSeries trendProtStop(0);
BoolSeries swingEntry(False);
Begin
If(!CallAuctionFilter()) Return;
cmiVal = Abs(Close - Close[29])/(Highest(High,30) - Lowest(Low,30))*100;
trendLokBuy = Average(Low,3);
trendLokSell= Average(High,3);
keyOfDay = (High + Low + Close)/3;
buyEasierDay = False;
sellEasierDay = False;
If(Close[1] > keyOfDay[1]) sellEasierDay = True;
If(Close[1] <= keyOfDay[1]) buyEasierDay = True;
myATR = AvgTrueRange(atrLength);
If(buyEasierDay == True)
{
swingBuyPt = Open + swingPrcnt1*myATR[1];
swingSellPt = Open - swingPrcnt2*myATR[1];
}
If(sellEasierDay == True)
{
swingBuyPt = Open + swingPrcnt2*myATR[1];
swingSellPt = Open - swingPrcnt1*myATR[1];
}
swingBuyPt = Max(swingBuyPt,trendLokBuy[1]);
swingSellPt = Min(swingSellPt,trendLokSell[1]);
MidLine = AverageFC(Close,bollingerLengths);
Band = StandardDev(Close,bollingerLengths,2);
upBand = MidLine + numStdDevs*Band;
dnBand = MidLine - numStdDevs*Band;
trendBuyPt = upBand;
trendSellPt = dnBand;
If(cmiVal[1] < swingTrendSwitch)
{
If(MarketPosition != -1 And Low <= swingSellPt)
{
SellShort(Lots,Min(Open,swingSellPt));
swingEntry = True;
}
If(MarketPosition == -1 And BarsSinceEntry >= 1 And High >= swingBuyPt)
{
BuyToCover(0,Max(Open,swingBuyPt));
swingEntry = False;
}
}
swingProtStop = 3*myATR;
trendProtStop = Average(Close,trendLiqLength);
If(cmiVal[1] >= swingTrendSwitch)
{
If(swingEntry == True)
{
If(MarketPosition == -1 And BarsSinceEntry >= 1 And High >= (EntryPrice + swingProtStop[1]))
{
BuyToCover(0,Max(Open,EntryPrice + swingProtStop[1]));
swingEntry = False;
}
}
If(swingEntry == False)
{
If(MarketPosition != -1 And BarsSinceExit >= 1 And Low <= trendSellPt[1])
{
SellShort(Lots,Min(Open,trendSellPt[1]));
}
If(MarketPosition == -1 And BarsSinceEntry >= 1 And High >= Min(trendBuyPt[1],trendProtStop[1]))
{
BuyToCover(0,Max(Open,Min(trendBuyPt[1],trendProtStop[1])));
}
}
}
End