天天看點

Python版恒溫器政策

趨勢行情不會永遠持續下去,事實上市場大部分時間都處于震蕩行情,是以才會有人希望能得到一種交易政策,既可以用在趨勢行情,也可以用在震蕩行情。那麼今天我們就用發明者量化交易平台,建構一個趨勢和震蕩行情通用的經典恒溫器政策。

提到恒溫器可能會有人想到汽車發動機與水箱之間的恒溫器。當發動機溫度低時,恒溫器是關閉狀态,此時發動機和水箱的水是不相通的,直到發動機溫度升高,達到最佳機油潤滑效果;當發動機溫度升高到一定門檻值時,節溫器是開啟狀态,此時發動機和水箱的水形成循環,并流經風扇開啟降溫模式,直到達到發動機最佳工作溫度。

那麼恒溫器政策也類似這個原理,并且延用了這個名字。它通過波動指數作為門檻值,将市場分為趨勢行情和震蕩行情,自動對兩種不同的行情使用對應的交易邏輯,有效彌補了趨勢政策在震蕩行情中的不适應。

如何把市場劃分為趨勢行情和震蕩行情,也就成了這個政策的關鍵,恒溫器政策引入了市場波動指數(Choppy Market Index),簡稱CMI。它是一個用來判斷市場走勢類型的技術名額。通過計算目前收盤價與N周期前收盤價的內插補點與這段時間内價格波動的範圍的比值,來判斷目前的價格走勢是趨勢還是震蕩。

CMI的計算公式為:

CMI=(abs(Close-ref(close,(n-1)))*100/(HHV(high,n)-LLV(low,n))

其中,abs是絕對值,n是周期數

一般來說CMI的值在0~100區間,值越大,趨勢越強。當CMI的值小于20時,政策認為市場處于震蕩模式;當CMI的值大于等于20時,政策認為市場處于趨勢模式。

  • 如果CMI < 20,執行震蕩政策;
  • 如果CMI ≥ 20,執行趨勢政策;

完整政策代碼

'''backtest
start: 2015-02-22 00:00:00
end: 2019-12-20 00:00:00
period: 1h
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

mp = 0  # 定義一個全局變量,用于控制虛拟持倉

# 政策主函數
def onTick():
    exchange.SetContractType("rb000")  # 訂閱期貨品種
    bar_arr = exchange.GetRecords()  # 擷取K線數組
    if len(bar_arr) < 100:  # 如果K線少于100根
        return  # 直接傳回
    close0 = bar_arr[-1]['Close']  # 擷取最新價格(賣價),用于開平倉
    bar_arr.pop()  # 删除K線數組最後一個元素,政策采用開平倉條件成立,下根K線交易模式
    
    # 計算CMI名額用以區分震蕩市與趨勢市
    close1 = bar_arr[-1]['Close']  # 最新收盤價
    close30 = bar_arr[-30]['Close']  # 前30根K線的收盤價
    hh30 = TA.Highest(bar_arr, 30, 'High')  # 最近30根K線的最高價
    ll30 = TA.Lowest(bar_arr, 30, 'Low')  # 最近30根K線的最低價
    cmi = abs((close1 - close30) / (hh30 - ll30)) * 100  # 計算市場波動指數

    # 震蕩市中收盤價大于關鍵價格為宜賣市,否則為宜買市
    high1 = bar_arr[-1]['High']  # 最新最高價
    low1 = bar_arr[-1]['Low']  # 最新最低價
    kod = (close1 + high1 + low1) / 3  # 計算關鍵價格
    if close1 > kod:
        be = 1
        se = 0
    else:
        be = 0
        se = 1
    
    # 計算10根K線ATR名額
    atr10 = TA.ATR(bar_arr, 10)[-1]

    # 定義最高價與最低價3日均線
    high2 = bar_arr[-2]['High']  # 上根K線最高價
    high3 = bar_arr[-3]['High']  # 前根K線最高價
    low2 = bar_arr[-2]['Low']  # 上根K線最低價
    low3 = bar_arr[-3]['Low']  # 前根K線最低價
    avg3high = (high1 + high2 + high3) / 3  # 最近3根K線最高價的均值
    avg3low = (low1 + low2 + low3) / 3  # 最近3根K線最低價的均值
    
    # 計算震蕩行情的進場價格
    open1 = bar_arr[-1]['Open']  # 最新開盤價
    if close1 > kod:  # 如果收盤價大于關鍵價格
        lep = open1 + atr10 * 3
        sep = open1 - atr10 * 2
    else:
        lep = open1 + atr10 * 2
        sep =