1 名词解释
置换均线:移位移动平均线也称置换移动平均线。置换均线(DMA)不是将当根bar上计算的均线值画上当根bar上,而是将历史的均线值画在当根bar上,使均线值整体向未来偏移了指定数量的bar。将移动平均K线向后平移一定BAR数即为置换均线。
Displaced Moving Average(DMA)是一种移动平均线的变体,它在计算移动平均线的基础上,将结果向前或向后平移若干周期。例如,如果将20天的简单移动平均线向前平移5天,就得到了一个15天的DMA。
DMA的作用与移动平均线类似,主要用于判断价格趋势的变化。与传统的移动平均线相比,DMA更具有前瞻性,因为它将移动平均线的结果向前或向后平移了若干个周期,能够更快地反映价格的变化趋势。同时,DMA也可以结合其他技术指标一起使用,如DMA与价格的交叉点,可以作为买卖信号的参考。
分析意义:
-
帮助确定价格趋势:DMA指标的变化可以反映价格趋势的变化。当DMA线向上突破零轴时,可以认为市场处于上升趋势;当DMA线向下突破零轴时,可以认为市场处于下降趋势。
-
帮助确定买卖时机:DMA指标的变化也可以作为买卖信号的参考。当DMA线向上突破零轴时,可以视为买入信号;当DMA线向下突破零轴时,可以视为卖出信号。
计算过程:
-
选择移动平均线的周期N和平移的周期M,这两个参数根据不同的市场和交易策略而定。
-
计算N周期的移动平均线,即使用收盘价CLOSE计算N周期的简单移动平均线MA(CLOSE,N)。
-
将计算结果向前或向后平移M个周期,得到位移后的DMA,即DMA = MA(CLOSE,N)Shift(M)。
其中,MA(CLOSE,N)是标准的移动平均线计算公式,Shift(M)表示将计算结果向前或向后平移M个周期。例如,如果将20天的简单移动平均线向前平移5天,就得到了一个15天的DMA。
2 参数设定
Params
Numeric AvgLength(5); //均线周期
Numeric AvgDisplace(5); //置换均线向后平移Bar数
Numeric ValidBars1(5); //开仓先决条件之一(收盘价上穿DMA均线)条件值保持有效的BAR数
Numeric ValidBars2(5); //开仓先决条件之二(上穿后再下穿)条件值保持有效的BAR数
Numeric ValidBars3(5); //开仓先决条件(上穿再下穿再上穿)条件值保持有效的BAR数
Numeric TrailStopBars(5); //多少根BAR的最低价作为跟踪止损价
-
AvgLength(均线周期):用于计算移动平均线的周期长度,默认为5。
-
AvgDisplace(置换均线向后平移Bar数):向后平移移动平均线的周期数,得到置换均线,默认为5。
-
ValidBars1(开仓先决条件之一):用于判断开仓时的先决条件之一,即收盘价上穿DMA均线,条件值保持有效的BAR数,默认为5。
-
ValidBars2(开仓先决条件之二):用于判断开仓时的先决条件之二,即上穿后再下穿,条件值保持有效的BAR数,默认为5。
-
ValidBars3(开仓先决条件之三):用于判断开仓时的先决条件之三,即上穿再下穿再上穿,条件值保持有效的BAR数,默认为5。
-
TrailStopBars(跟踪止损的BAR数):用于设置跟踪止损的BAR数,即多少根BAR的最低价作为跟踪止损价,默认为5。
Vars
Numeric ConCrossOver; //当前BAR是否上穿DMA
Numeric ConCrossUnder; //当前BAR是否下穿DMA
Numeric BarsLastCrsUndL; //多头最近一次下穿离现在的BAR数
Numeric BarsFstCrsOvrL; //多头最近倒数第二次上穿离现在的BAR数
Numeric BarsSecCrsOvrL; //多头最近的一次上穿离现在的BAR数
Numeric BarsLastCrsOvrS; //空头最近一次上穿离现在的BAR数
Numeric BarsFstCrsUndS; //空头最近倒数第二次下穿离现在的BAR数
Numeric BarsSecCrsUndS; //空头最近的一次下穿离现在的BAR数
Numeric ReversalPriceL; //多头趋势反向的平仓价格
Numeric TrailStopPriceL; //多头跟踪止损的平仓价格
Numeric ReversalPriceS; //空头趋势反向的平仓价格
Numeric TrailStopPriceS; //开工跟踪止损的平仓价格
NumericSeries MA1; //均线
NumericSeries DMA1; //置换均线
NumericSeries EntryFlagL; //多头开仓标志
NumericSeries EntryPointL; //多头突破开仓的价格
NumericSeries EntryCountL; //多头满足开仓先决条件的BAR计数
NumericSeries EntryFlagS; //空头开仓标志
NumericSeries EntryPointS; //空头突破开仓的价格
NumericSeries EntryCountS; //空头满足开仓先决条件的BAR计数
-
ConCrossOver(当前BAR是否上穿DMA):用于记录当前的BAR是否上穿了DMA。
-
ConCrossUnder(当前BAR是否下穿DMA):用于记录当前的BAR是否下穿了DMA。
-
BarsLastCrsUndL(多头最近一次下穿离现在的BAR数):用于记录多头最近一次下穿DMA离当前BAR的数量。
-
BarsFstCrsOvrL(多头最近倒数第二次上穿离现在的BAR数):用于记录多头最近一次上穿DMA的倒数第二个BAR离当前BAR的数量。
-
BarsSecCrsOvrL(多头最近一次上穿离现在的BAR数):用于记录多头最近一次上穿DMA离当前BAR的数量。
-
BarsLastCrsOvrS(空头最近一次上穿离现在的BAR数):用于记录空头最近一次上穿DMA离当前BAR的数量。
-
BarsFstCrsUndS(空头最近倒数第二次下穿离现在的BAR数):用于记录空头最近一次下穿DMA的倒数第二个BAR离当前BAR的数量。
-
BarsSecCrsUndS(空头最近一次下穿离现在的BAR数):用于记录空头最近一次下穿DMA离当前BAR的数量。
-
ReversalPriceL(多头趋势反向的平仓价格):用于记录多头趋势反向时的平仓价格。
-
TrailStopPriceL(多头跟踪止损的平仓价格):用于记录多头跟踪止损时的平仓价格
3 信号发出
计算置换均线
MA1 = Ma(Close,AvgLength);
DMA1 = MA1[AvgDisplace];
PlotNumeric("DMA",DMA1);
判断收盘价是否穿越置换均线
ConCrossOver = CrossUp(Close,DMA1);
ConCrossUnder = CrossDown(Close,DMA1);
计算各种条件下的BAR数值
-
BarsLastCrsUndL: 多头最近一次下穿DMA离当前BAR的根数。BarsLast函数返回符合条件的最后一个Bar的位置,ConCrossUnder==1表示当前Bar下穿DMA,因此计算的是离当前Bar最近的下穿DMA的Bar与当前Bar之间的Bar数量。
-
BarsLastCrsOvrS: 空头最近一次上穿DMA离当前BAR的根数。BarsLast函数同上,只是这里是计算空头的情况,即当前Bar上穿DMA。
-
BarsFstCrsOvrL: 多头最近的两次上穿DMA离当前BAR的根数中的第一次。SumBars函数是自定义函数,用于计算符合条件的根数之和。这里是计算多头上穿DMA的情况,SumBars(ConCrossOver == 1, 2)表示当前Bar与前两个Bar的上穿DMA情况,减去1是为了得到最近两次上穿DMA中的第一次。
-
BarsSecCrsOvrL: 多头最近的两次上穿DMA离当前BAR的根数中的第二次。BarsLast函数同上,只是这里是计算多头的情况,即当前Bar上穿DMA。
-
BarsFstCrsUndS: 空头最近的两次下穿DMA离当前BAR的根数中的第一次。SumBars函数同上,只是这里是计算空头的情况,即当前Bar下穿DMA。
-
BarsSecCrsUndS: 空头最近的两次下穿DMA离当前BAR的根数中的第二次。BarsLast函数同上,只是这里是计算空头的情况,即当前Bar下穿DMA。
//多头计算最近的一次下穿发生的BAR离当前BAR的根数
BarsLastCrsUndL = BarsLast(ConCrossUnder == 1);
//空头计算最近的一次上穿发生的BAR离当前BAR的根数
BarsLastCrsOvrS = BarsLast(ConCrossOver == 1);
//多头 计算最近的两次上穿发生的BAR离当前BAR的根数
BarsFstCrsOvrL = SumBars(ConCrossOver == 1,2) - 1;
BarsSecCrsOvrL = BarsLast(ConCrossOver == 1);
//空头计算最近的两次下穿发生的BAR离当前BAR的根数
BarsFstCrsUndS = SumBars(ConCrossUnder == 1,2) - 1;
BarsSecCrsUndS = BarsLast(ConCrossUnder == 1);
开仓标志
-
如果
ConCrossOver == 1
,表示发生了多头上穿信号,且最近的一次下穿发生的BAR离当前BAR的根数-最近的两次上穿发生第二次的BAR离当前BAR的根数 不超过ValidBars2
,同时最近的两次上穿发生第一次的BAR离当前BAR的根数-多头计算最近的一次下穿发生的BAR离当前BAR的根数 不超过ValidBars1
,则设置多头开仓标志EntryFlagL
为1,表示可以开多头仓位。此外,将多头的开仓点设置为当前价格加上MinMove * PriceScale
,同时将多头的开仓次数EntryCountL
设置为0。 -
如果
ConCrossUnder == 1
,表示发生了空头下穿信号,且最近的一次上穿发生的BAR离当前BAR的根数-最近的两次下穿发生第二次的BAR离当前BAR的根数 不超过ValidBars2
,同时最近的两次下穿发生第一次的BAR离当前BAR的根数-多头计算最近的一次上穿发生的BAR离当前BAR的根数 不超过ValidBars1
,则设置空头开仓标志EntryFlagS
为1,表示可以开空头仓位。此外,将空头的开仓点设置为当前价格减去MinMove * PriceScale
,同时将空头的开仓次数EntryCountS
设置为0。
//设置多头开仓标志
If(ConCrossOver == 1 && BarsLastCrsUndL - BarsSecCrsOvrL <= ValidBars2 && BarsFstCrsOvrL - BarsLastCrsUndL <= ValidBars1)
{
EntryFlagL = 1;
EntryPointL = High + MinMove * PriceScale;
EntryCountL = 0;
}
//设置空头开仓标志
If(ConCrossUnder == 1 && BarsLastCrsOvrS - BarsSecCrsUndS <= ValidBars2 && BarsFstCrsUndS - BarsLastCrsOvrS <= ValidBars1)
{
EntryFlagS = 1;
EntryPointS = Low - MinMove * PriceScale;
EntryCountS = 0;
}
系统入场
如果尝试多头开仓的次数 EntryCountL
还没有达到最大尝试次数 ValidBars3
,那么程序才会继续执行下面的开仓操作。如果已经尝试开仓的次数 EntryCountL
达到了规定的最大次数 ValidBars3
,则程序不会再尝试开仓。这个条件语句是为了避免程序在一次尝试开仓失败后一直尝试开仓,从而避免出现过度交易的情况。
对于多头开仓,如果多头开仓标志为1(即满足开仓条件),且当前价格高于设置的开仓点(EntryPointL),同时成交量大于0,则执行买入开仓操作(BK),否则增加开仓计数器(EntryCountL)。
对于空头开仓,如果空头开仓标志为1(即满足开仓条件),且当前价格低于设置的开仓点(EntryPointS),同时成交量大于0,则执行卖出开仓操作(SK),否则增加开仓计数器(EntryCountS)。
//多头开仓
If(MarketPosition == 0 && EntryCountL <= ValidBars3)
{
If(EntryFlagL == 1 && High >= EntryPointL && Vol > 0)
{
BK(DefaultVol);
}
Else
{
EntryCountL = EntryCountL + 1;
}
}
//空头开仓
If(MarketPosition == 0 && EntryCountS <= ValidBars3)
{
If(EntryFlagS == 1 && Low <= EntryPointS && Vol > 0)
{
SK(DefaultVol);
}
Else
{
EntryCountS = EntryCountS + 1;
}
}
更新多头和空头开仓的标志以及计算止损价格
首先,对于多头,如果当前仓位是多头仓位或者开仓先决条件已过有效BAR数,那么就将多头开仓标志设置为0。这里的EntryCountL是记录开仓先决条件已过的BAR数,而ValidBars3是限制开仓先决条件必须过多少个BAR才能开仓的阈值。
接着,计算多头的止损价格,ReversalPriceL是DMA1向下移动一个单位所得到的价格减去一个最小跳动价MinMove的距离,而TrailStopPriceL是过去TrailStopBars个BAR中的最低价。
对于空头,与多头的处理方式类似,如果当前仓位是空头仓位或者开仓先决条件已过有效BAR数,就将空头开仓标志设置为0。然后,计算空头的止损价格,ReversalPriceS是DMA1向上移动一个单位所得到的价格加上一个最小跳动价MinMove的距离,而TrailStopPriceS是过去TrailStopBars个BAR中的最高价。
//多头开仓或者开仓先决条件已过有效BAR数,修改开仓标志
If(MarketPosition == 1 || EntryCountL > ValidBars3)
{
EntryFlagL = 0;
}
//多头止损价格计算
ReversalPriceL = DMA1[1] - MinMove * PriceScale;
TrailStopPriceL = LLV(Low[1],TrailStopBars);
//空头开仓或者开仓先决条件已过有效BAR数,修改开仓标志
If(MarketPosition == -1 || EntryCountS > ValidBars3)
{
EntryFlagS = 0;
}
//空头止损价格计算
ReversalPriceS = DMA1[1] + MinMove * PriceScale;
TrailStopPriceS = HHV(High[1],TrailStopBars);
系统出场
MarketPosition
等于1表示当前持有多头头寸,BarsSinceEntry
表示自开仓后已经经过的时间(K线数),Vol
表示成交量,如果成交量大于0说明有成交,表示当前价格有实际买卖交易发生。如果满足条件Low <= Max(ReversalPriceL,TrailStopPriceL)
,即当前价格已经低于最近的反转价位或者移动止损价位,则平仓多头头寸。
MarketPosition
等于-1表示当前持有空头头寸,其他参数的含义和解释与平多仓相同。如果满足条件High >= Min(ReversalPriceS,TrailStopPriceS)
,即当前价格已经高于最近的反转价位或者移动止损价位,则平仓空头头寸。
//多头平仓
If(MarketPosition == 1 && BarsSinceEntry > 0 && Vol > 0)
{
If(Low <= Max(ReversalPriceL,TrailStopPriceL))
{
SP(DefaultVol);
}
}
//空头平仓
If(MarketPosition == -1 && BarsSinceEntry > 0 && Vol > 0)
{
If(High >= Min(ReversalPriceS,TrailStopPriceS))
{
BP(DefaultVol);
}
}
4 策略总结
该系统的优点在于,通过使用DMA作为均线指标,可以有效地过滤掉价格波动的噪声,从而减少了假信号的产生。同时,该系统还考虑了二次穿越的情况,从而可以进一步排除不可靠的信号。不过,该系统也有一些缺点,比如在市场出现大幅波动时,可能会出现较大的滑点,从而影响交易结果。
系统要素:
-
将移动平均K线向后平移一定BAR数即为置换均线
-
相隔一定BAR数的收盘价二次穿越置换均线
-
二次穿越完成时那根BAR的高点(或低点)作为突破进场价
-
完成二次穿越的一定BAR数内突破
入场条件:
-
有效期内价格向上突破设定进场价做多
-
有效期内价格向下突破设定进场价做空
出场条件:
-
价格反向穿越均线后止损
-
基于N根K线的高低点的跟踪止损
5 Q&A
-
函数使用
CrossUp(A,B) 表当A从下方向上穿过B,成立返回1(True),否则返回0(False)
CrossDown(A,B):表示当A从上方向下穿B,成立返回1(True),否则返回0(False)
BarsLast(Cond) 上一次条件Cond成立到当前的周期数
SumBars(X,A):求累加到指定值的周期数
SumBars(Vol,20000); 将成交量向前累加直到大于等于20000,返回这个区间的周期数。
-
图鉴
名称 |
代码 |
含义 |
ConCrossOver |
CrossUp(Close,DMA1) |
收盘价是否上穿置换均线 |
ConCrossUnder |
CrossDown(Close,DMA1) |
收盘价是否下穿置换均线 |
BarsLastCrsUndL |
BarsLast(ConCrossUnder == 1) |
多头计算最近的一次下穿发生的BAR离当前BAR的根数 |
BarsLastCrsOvrS |
BarsLast(ConCrossOver == 1) |
空头计算最近的一次上穿发生的BAR离当前BAR的根数 |
BarsFstCrsOvrL |
SumBars(ConCrossOver == 1,2) - 1 |
多头计算最近的两次上穿发生的BAR离当前BAR的根数 前一次 |
BarsSecCrsOvrL |
BarsLast(ConCrossOver == 1) |
多头计算最近的两次上穿发生的BAR离当前BAR的根数 后一次 |
BarsFstCrsUndS |
SumBars(ConCrossUnder == 1,2) - 1 |
空头计算最近的两次下穿发生的BAR离当前BAR的根数 前一次 |
BarsSecCrsUndS |
BarsLast(ConCrossUnder == 1) |
空头计算最近的两次下穿发生的BAR离当前BAR的根数 后一次 |
-
开仓标志
多头:
在这里,条件 ConCrossOver == 1
是指当收盘价向上穿越置换均线时,发出多头开仓信号。然后,另外两个条件 BarsLastCrsUndL - BarsSecCrsOvrL <= ValidBars2
和 BarsFstCrsOvrL - BarsLastCrsUndL <= ValidBars1
是为了确认此时的多头开仓信号是可靠的。
BarsLastCrsUndL - BarsSecCrsOvrL <= ValidBars2
多头计算最近的一次下穿发生的BAR离当前BAR的根数 和 多头计算最近的两次上穿发生的BAR离当前BAR的根数后一次 的距离 小于 ValidBars2
BarsFstCrsOvrL - BarsLastCrsUndL <= ValidBars1
多头计算最近的两次上穿发生的BAR离当前BAR的根数 前一次 和 多头计算最近的一次下穿发生的BAR离当前BAR的根数 的距离
如果最近一次下穿 DMA1 的时间太近,可能代表 DMA1 的趋势正在向下,而不是向上,这种情况下开多仓就不是很明智。因此,需要确保已经有足够的时间让 DMA1 的趋势向上转变,才可以考虑开多仓。
具体而言,如果最近一次下穿 DMA1 的时间距离当前时间不足 ValidBars2 个周期,就意味着 DMA1 的趋势可能还没有完全向上转变,可能仍在下降阶段。因此,在这种情况下,如果开多仓,可能会遭受亏损。因此,需要等待一段时间,以确保 DMA1 趋势已经向上转变,再考虑开多仓。
同时,BarsFstCrsOvrL - BarsLastCrsUndL <= ValidBars1 这个条件是为了进一步确认 DMA1 趋势已经向上转变。如果最近一次下穿 DMA1 距离当前时间不超过 ValidBars2 个周期,但是在这个时间段内,DMA1 已经出现了多次上穿的情况,那么就可以确认 DMA1 趋势已经向上转变,可以考虑开多仓。因此,这个条件进一步提高了开仓的可靠性和成功率。
-
止损价格
其中,ReversalPriceL的计算是在DMA1的前一周期(即DMA1[1])的基础上减去一个MinMove * PriceScale的值。这里的MinMove代表一个最小的价格波动单位,而PriceScale则是一个价格缩放因子。这个计算可以看作是将DMA1的前一周期的价格向下偏移一定的距离,从而得到多头止损的价格。
而TrailStopPriceL的计算则是取DMA1前一周期到当前周期中的最低价的最小值,并在此基础上再向下偏移TrailStopBars个周期的价格波动单位,从而得到跟踪止损的价格。这里的TrailStopBars代表跟踪止损的时间窗口大小,即向前多少个周期进行跟踪止损。文章来源:https://www.toymoban.com/news/detail-816246.html
这样设计的目的是为了尽可能减小多头开仓的风险,同时也考虑到了价格的波动性和跟踪止损的必要性。在实际交易中,这个计算可能还会包括一些额外的因素,比如手续费和滑点等,以更加准确地估算止损价格。文章来源地址https://www.toymoban.com/news/detail-816246.html
到了这里,关于基于置换均线的二次穿越突破均线的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!