当前位置: 华文世界 > 股票

13年回测年化收益100%的CMO指标改写量化策略

2024-06-30股票

CMO指标

全称为Chande Momentum Oscillator(钱德动量震荡指标),是由技术分析师图莎尔·钱德(Tushar S. Chande)发明的一种技术指标。它用于衡量市场上的买方和卖方力量之间的差异,以此来判断资产是否处于超买或超卖状态。

CMO指标与相对强弱指数(RSI)类似,但计算方式有所不同。CMO在计算过程中同时考虑了价格上涨日和价格下跌日的幅度,而不仅仅是比例。

具体计算步骤如下

1. 确定时间周期:首先,选择一个时间周期(如14天、20天等),这是CMO指标的一个参数。

2. 计算上升总和(SU)和下降总和(SD):

- 对于每个时间周期内的每一天,如果当天的收盘价高于前一天,则记录这个差值;所有这些正差值的总和就是上升总和(SU)。

- 如果当天的收盘价低于前一天,则记录这个差值的绝对值;所有这些负差值绝对值的总和就是下降总和(SD)。

3. 计算CMO值:

CMO指标算法

CMO指标的值通常在-100到+100之间变化:

- 当CMO接近+100时,表明市场可能过度买入,有回调的风险。

- 当CMO接近-100时,表明市场可能过度卖出,有反弹的可能性。

CMO指标的默认时间周期通常是14天或20天,但这可以根据个人偏好和市场情况调整。使用CMO时,交易者通常会结合其他技术分析工具和图表模式,以提高交易决策的准确性。

金融民工还是选择 量化交易平台(交易开拓者)TradeBlazer 进行策略开发和验证

怎么运用算法把CMO指标线画出来?

// 简称: CMO

// 名称: 纯动力振荡指标

// 类别: 公式应用

// 类型: 内建应用

//------------------------------------------------------------------------

Params

Numeric Length(20);

Vars

Numeric CMOValue;

NumericSeries CloseUp;

NumericSeries CloseDown;

Numeric SumCloseUp;

Numeric SumCloseDown;

Begin

if(CurrentBar == 0)

{

CMOValue=0;

}Else

{

If(Close > Close[1])

{

CloseUp=Close - Close[1];

CloseDown=0;

}

If(Close < Close[1])

{

CloseUp=0;

CloseDown=Close[1] - Close;

}

If(Close == Close[1])

{

CloseUp=0;

CloseDown=0;

}

SumCloseUp = SummationFC(CloseUp,Length);

SumCloseDown = SummationFC(CloseDown,Length);

If(SumCloseUp + SumCloseDown <> 0)

CMOValue =( SumCloseUp - SumCloseDown)/(SumCloseUp + SumCloseDown)*100;算法公式

}

PlotNumeric("CMO",CMOValue);

PlotNumeric("Ref1",50);

PlotNumeric("Ref2",-50);

End

上述策略代码就是CMO指标算法

下面就是通过算法画出的CMO指标线,CMO指标线比较舒缓,我们发现对衍生品走势还跟踪的方向是较为一致的

CMO指标线

怎么通过CMO的指标算法,改写一个可以实盘交易的CMO量化策略呢?

这段策略代码使用了CMO指标以及移动平均线(MA)来决定买入和卖出时机,同时设置了止盈止损点。下面是对代码的逐行注释和解释:

梳理策略逻辑:

策略核心逻辑:

1. 计算移动平均线:使用`DslowLength`作为周期计算移动平均线,决定大方向

2.计算CMO指标:

- 判断当前价格相对于前一日的变化,更新`CloseUp`和`CloseDown`。

- 计算近`Length`周期内价格上涨和下跌的累积和。

- 若累积和不为零,计算CMO指标值。

3. 交易信号过滤:通过`CallAuctionFilter()`确保非集中交易时间执行交易。

5. 买入信号:

- 当前未持有仓位(`MarketPosition <> 1`),且CMO指标由负转正,同时收盘价高于长期移动平均线时,买入。

6. 卖出/做空信号:

- 当前无空头仓位(`MarketPosition <> -1`),且CMO指标由正转负,同时收盘价低于长期移动平均线时,卖出或做空。

策略说明:

- 入场逻辑:当CMO指标从下方穿过0轴且当日收盘价高于长期移动平均线时,买入;反之,当CMO指标从上方穿过0轴且收盘价低于长期移动平均线时,卖出或做空。

- 出场逻辑:设置了固定的止盈和止损点数,一旦达到设定的目标价位或止损价位,即执行相应的平仓操作。

- 过滤逻辑:使用了`CallAuctionFilter()`函数,确保不在拍卖阶段执行交易指令,避免市场开盘或收盘时的异常波动影响。

策略编写:

// 定义策略参数

Numeric Length(9); // CMO计算的时间周期,默认为9

Numeric DslowLength(160); // 移动平均线的时间周期,默认为160

// 定义变量

Vars NumericSeries CMOValue; // CMO指标值

NumericSeries CloseUp; // 上升天数的价格变动

NumericSeries CloseDown; // 下降天数的价格变动

Numeric SumCloseUp; // 近期上升天数的价格变动总和

Numeric SumCloseDown; // 近期下降天数的价格变动总和

NumericSeries AvgValue3; // 移动平均线值

Numeric MinPoint; // 最小变动单位

Numeric MyEntryPrice; // 入场价格

Numeric TakeProfitSet(120); // 止盈点数

Numeric StopLossSet(30); // 止损点数

Numeric MyExitPrice; // 出场价格

Begin

// 计算移动平均线

AvgValue3 = AverageFC(Close,DslowLength);

PlotNumeric("MA3",AvgValue3); // 绘制移动平均线

// 初始化CMOValue

if(CurrentBar == 0)

{

CMOValue=0;

}else

{

// 计算CloseUp和CloseDown

If(Close > Close[1])

{

CloseUp=Close - Close[1];

CloseDown=0;

}

If(Close < Close[1])

{

CloseUp=0;

CloseDown=Close[1] - Close;

}

If(Close == Close[1])

{

CloseUp=0;

CloseDown=0;

}

// 累加CloseUp和CloseDown

SumCloseUp = SummationFC(CloseUp,Length);

SumCloseDown = SummationFC(CloseDown,Length);

// 计算CMOValue

If(SumCloseUp + SumCloseDown <> 0)

CMOValue =( SumCloseUp - SumCloseDown)/(SumCloseUp + SumCloseDown)*100;

}

// 检查是否在拍卖阶段

If(!CallAuctionFilter()) Return;

// 买入条件

If(MarketPosition <> 1 And CrossOver(CMOValue[1],0) And Close[1] >AvgValue3)

{

Buy(1,Open); // 在CMO从下向上穿过0轴且收盘价大于MA时买入

}

// 卖出条件

If(MarketPosition <> -1 And CrossUnder(CMOValue[1],0) And Close[1] < AvgValue3)

{

SellShort(1,Open); // 在CMO从上向下穿过0轴且收盘价小于MA时做空

}

// 设置最小变动单位

MinPoint = MinMove*PriceScale;

// 记录入场价格

MyEntryPrice = AvgEntryPrice;

// 处理平仓逻辑

If(MarketPosition==1) // 如果是多头

{

// 止盈

If(High >= MyEntryPrice + TakeProfitSet*MinPoint)

{

MyExitPrice = MyEntryPrice + TakeProfitSet*MinPoint;

If(Open > MyExitPrice) MyExitPrice = Open;

Sell(0,MyExitPrice);

}else if(Low <= MyEntryPrice - StopLossSet*MinPoint) // 止损

{

MyExitPrice = MyEntryPrice - StopLossSet*MinPoint;

If(Open < MyExitPrice) MyExitPrice = Open;

Sell(0,MyExitPrice);

}

}else if(MarketPosition==-1) // 如果是空头

{

// 止盈

If(Low <= MyEntryPrice - TakeProfitSet*MinPoint)

{

MyExitPrice = MyEntryPrice - TakeProfitSet*MinPoint;

If(Open < MyExitPrice) MyExitPrice = Open;

BuyToCover(0,MyExitPrice);

}else if(High >= MyEntryPrice + StopLossSet*MinPoint) // 止损

{

MyExitPrice = MyEntryPrice + StopLossSet*MinPoint;

If(Open > MyExitPrice) MyExitPrice = Open;

BuyToCover(0,MyExitPrice);

}

}

End

使用焦炭连续30分钟K线进行策略回测:

收益曲线非常漂亮

年化收益100%

13年的数据回测,样本数据足够多

策略信号展示

策略回测了过去将近13年时间,年化收益100%,仅有2011年微亏,其它年份全部盈利,

该策略的胜率不高,仅有27%,但是回撤控制非常好,遵循这小亏大赚的原则,所以该策略是一个非常不错的优质策略,需要进一步进行优化。