當前位置: 華文世界 > 股票

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%,但是回撤控制非常好,遵循這小虧大賺的原則,所以該策略是一個非常不錯的優質策略,需要進一步進行最佳化。