来源:mc官网
(策略:Alex)
市场的行情大致分为两类,一个是震荡行情,另一个是趋势行情。如果根据市场的行情来区分策略,那么策略也可以分为两类,一个是震荡性策略,另一个是趋势性策略。
道理大家都懂,但是我们往往很难做到在一个策略里同时处理趋势和震荡行情,看看我们今天的分享,或许你会获得灵感……
一、什么是恒温器系统
广义上来说,既有趋势性又有震荡性的策略,称之为恒温器系统,它基于某个标准会自动在震荡行情和趋势行情进行调节交易行为。
从细节上来说,不同的恒温器系统内部是不一样的,主要体现在三个重要的细节上:震荡性策略(对于震荡行情的处理);趋势性策略(对于趋势行情的处理);判断当前行情的标准。
二、策略逻辑
今天介绍两个恒温器系统,第一个是最初也是最经典的恒温器系统,第二个是我们做了改进后的系统,一起来看看吧!
振荡策略基于价格突破策略:
买入进场突破价格是下一根bar的开盘价+10日ATR的一定比例;
卖出进场突破价是下一根bar的开盘价-10日ATR的一定比例;
这里做了一点细节处理,将买入进场突破价格与最近3根bar的最低价的平均价进行比较,取较大值作为最终的买入进场突破价格,
将卖出进场突破价格与最近3根bar的最高价的平均价进行比较,取较小值作为最终的卖出进场突破价格。
趋势策略基于布林带策略:
当cmi<20时,使用振荡策略;
当cmi>=20时,使用趋势策略;
当cmi>=20时,也就是恒温器判断当前的行情为趋势行情,此时若当前有一笔振荡策略的多头持仓,那么当价格跌破进场价格之下3倍ATR时,执行多头出场。
2. MC_Thermostat
振荡策略是基于KDJ的一个策略:
当K大于D,并且D小于30时,多头进场;
当K小于D,并且D大于70时,空头进场;
当K小于D,并且收盘价大于进场价一定比例之后多头出场;
当K大于D,并且收盘价小于进场价一定比例之后空头出场。
趋势策略是基于布林带策略:
收盘价突破上轨时,多头进场;
收盘价突破下轨时,空头进场;
收盘价跌破布林中轨时,多头出场;
收盘价突破布林中轨时,空头出场。
当函数cmi小于20时,使用振荡策略;
当函数cmi大于等于20时,使用趋势策略。
三、绩效
图1. 策略设置
图2. 详细权益曲线
代码:
input: length(numericsimple), smoothlength(numericsimple), var_K(numericref), var_D(numericref), var_J(numericref);
var: high1(0), low1(0), rsv(0);
high1=highest(high,length);
low1=lowest(low,length);
if high1<>low1 then
rsv=(close-low1)/(high1-low1)*100
else rsv=0;
var_k=xaverageorig(rsv,smoothlength);
var_d=xaverageorig(var_k,smoothlength);
var_j=3var_k-2var_d;
Inputs: bollingerLengths(50),trendLiqLength(50),numStdDevs(2),
swingPrcnt1(0.50),swingPrcnt2(0.75),atrLength(10),
swingTrendSwitch(20);
Vars:cmiVal(0),buyEasierDay(0),sellEasierDay(0),trendLokBuy(0),
trendLokSell(0),keyOfDay(0),swingBuyPt(0),swingSellPt(0),
trendBuyPt(0),trendSellPt(0),swingProtStop(0);
value1=highest(high,30)-lowest(low,30);
if value1<>0 then
cmiVal=absvalue(close-close[29])/value1*100;
buyEasierDay = 0;
sellEasierDay = 0;
trendLokBuy = Average(Low,3);
trendLokSell= Average(High,3);
keyOfDay = (High + Low + Close)/3;
if(Close > keyOfDay) then sellEasierDay = 1;
if(Close <= keyOfDay) then buyEasierDay = 1;
if(buyEasierDay = 1) then
begin
swingBuyPt = Open next bar + swingPrcnt1*AvgTrueRange(atrLength);
swingSellPt = Open next bar-swingPrcnt2*AvgTrueRange(atrLength);
end;
if(sellEasierDay = 1) then
begin
swingBuyPt = Open next bar + swingPrcnt2*AvgTrueRange(atrLength);
swingSellPt = Open next bar-swingPrcnt1*AvgTrueRange(atrLength);
end;
swingBuyPt = MaxList(swingBuyPt,trendLokBuy);
swingSellPt = MinList(swingSellPt,trendLokSell);
trendBuyPt = BollingerBand(Close,bollingerLengths,numStdDevs);
trendSellPt = BollingerBand(Close,bollingerLengths,- numStdDevs);
if(cmiVal < swingTrendSwitch)then
begin
if (MarketPosition <> 1) then Buy(“SwingBuy”) next bar at swingBuyPt stop;
if(MarketPosition <> -1) then SellShort(“SwingSell”) next bar at swingSellPt stop;
end
else
begin
swingProtStop = 3*AvgTrueRange(atrLength);
Buy(“TrendBuy”) next bar at trendBuyPt stop;
SellShort(“TrendSell”) next bar at trendSellPt stop;
Sell from Entry(“TrendBuy”) next bar at Average(Close,trendLiqLength) stop;
BuyToCover from Entry(“TrendSell”) next bar at Average(Close,trendLiqLength) stop;
Sell from Entry(“SwingBuy”) next bar at entryprice-swingProtStop stop;
BuyToCover from Entry(“SwingSell”) next bar at entryprice +swingProtStop stop;
end;
inputs: profit(3),length(50);
var: upline(0), downline(0), ma(0), var_k(0), var_d(0), var_j(0), cmi(0), lot(1);
upline=BollingerBand(close,50,2);
downline=BollingerBand(close,50,-2);
ma=average(close,50);
Alex_KDJ(9,3,var_k,var_d,var_j);
value1=highest(high,30)-lowest(low,30);
if value1<>0 then
cmi=absvalue(close-close[29])/value1*100;
if cmi<20 then begin
if var_k > var_d and var_d<30 then
buy(“swing_b”) lot shares next bar at market
else if var_k < var_d and var_d>70 then
sellshort(“swing_s”) lot shares next bar at market;
end
else if cmi>=20 then begin
if close cross above upline then
buy(“trend_b”) lot shares next bar at market
else if close cross under downline then
sellshort(“trend_s”) lot shares next bar at market;
end;
if var_k
sell from entry(“swing_b”) next bar at market
else if var_k>var_d and close buytocover from entry(“swing_s”) next bar at market; if close cross under ma then sell from entry(“trend_b”) next bar at market else if close cross above ma then buytocover from entry(“trend_s”) next bar at market;