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