溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

python如何實現(xiàn)動態(tài)階梯突破策略

發(fā)布時間:2022-01-15 15:11:01 來源:億速云 閱讀:326 作者:小新 欄目:互聯(lián)網(wǎng)科技

這篇文章給大家分享的是有關python如何實現(xiàn)動態(tài)階梯突破策略的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

什么是突破策略

我們知道,期貨市場的價格以趨勢和震蕩交替的方式演變,如果我們只使用一種方法抓住趨勢,就能賺到趨勢行情的錢。那么,用什么方式來抓住趨勢呢?比較簡單的一種方法就是用突破策略。通過設置價格的上下軌,或者支撐位、壓力位,當價格超過上軌,我們認為行情即將啟動,開倉做多,反之亦然。

市面上有很多不同種類的突破策略,大致可以分為:形態(tài)突破(包括:雙肩型、頭肩型、頸線、趨勢線等等)、指標突破(均線、KDJ、ATR等等)、通道突破(新高和新低、支撐線和阻力線)、量能突破(成交量、能量潮)。其中在量化交易中,最常用的是:指標突破和通道突破。

突破策略理論

在邏輯學中,有一個“充分不必要條件”的概念,也就是說:如果有A不一定有B,但如果有B就必定有A。那么B就是A的充分而不必要的條件,即充分不必要條件,A是B的必要不充分條件。所以站在結(jié)果的角度講,價格突破關鍵點位后未必形成趨勢,但趨勢上漲或下跌必然會突破其間的關鍵價格位置。

另外,從突破的原因上講,市場漲跌取決于買賣雙方實力對比。當價位沖破上一時段的最高點時,在上一時段任何價位做空頭的人都無一例外被套牢,它當中肯定有一部分要認賠平倉出局,反過來又給升勢推波助瀾。相反,當行情跌破上一時段的最低價時,在上一時段任何一點做多頭的統(tǒng)統(tǒng)都出現(xiàn)浮動虧損,其中一定有部分要止損作平倉賣出,正好對跌勢落井下石。

策略邏輯

階梯策略,這是一個比較土的名字,因為其在圖表上的外形類似臺階而得名,最初的靈感來自于階梯止損。相信有過實盤經(jīng)驗的人應該深有體會:當市場進行橫向整理或者搖擺不定的時候,對交叉類系統(tǒng)的打擊很大,往往會買在高點,賣在低點。如果行情一直持續(xù),則會出現(xiàn)連續(xù)虧損,連續(xù)的虧損信號將對交易者造成嚴重的心理負擔和資金回撤壓力。如下圖:

python如何實現(xiàn)動態(tài)階梯突破策略

通過利用,通道技術則可以過濾或者減少價格反復纏繞,減少部分虛假信號,對于降低無效交易有巨大幫助。本策略并非傳統(tǒng)的通道策略。而是根據(jù)前期最高價和最低價,反向建立自適應通道。這里提到的自適應是指回溯日期會根據(jù)我們的邏輯進行調(diào)整,具體來說本策略是由市場波動的變動率來變化。

大部分通道策略的組成是由兩個因子決定,第一個就是中軌,然后再根據(jù)中軌算出通道寬度,即上下軌。比如常見的布林帶通道( BollingerBand ),先是由一條均線當中心線,而通道寬度是由標準差所決定。階梯策略的通道并不是以中軌得來,與之相反的是:先根據(jù)市場波動率計算出通道上下軌,然后再根據(jù)通道寬度算出中軌。

另外,在判定最高點和最低點的 K 線條數(shù)取決于我們愿意給交易多少變化空間,我們用來越多的 K 線條數(shù)來確定上下軌,我們給予程序化交易的變化空間越大,相應的,在觸發(fā)止損前盈利回撤的幅度也會越大。使用越近的高點或低點,止損被觸發(fā)的速度也越快。想讓通道窄一點就設定小一點,想讓通道寬一點就設定大一點。

python如何實現(xiàn)動態(tài)階梯突破策略

設置通道

  • 上軌:如果當根K線最低價小于上根K線最低價,上軌就等于前N根K線最高價的最高價

  • 下軌:如果當根K線最高價大于上根K線最高價,下軌就等于前N根K線最低價的最低價

  • 中軌:上軌和下軌的平均值

入場條件

  • 多頭入場:如果當前沒有持倉,并且價格大于上軌,買入開倉。

  • 空頭入場:如果當前沒有持倉,并且價格小于下軌,賣出開倉。

出場條件

  • 多頭出場:如果當前持有多單,并且價格小于中軌,賣出平倉。

  • 空頭出場:如果當前持有空單,兵器價格大于中軌,買入平倉。

為了避免過度擬合,在設計策略的時候,只給定了一個參數(shù)。雖然僅有一個參數(shù),但卻不失策略在市場中的靈活性。不僅如此,階梯策略既能適應國內(nèi)外商品期貨,還可以應用于 A 股 ETF ,包括外盤 ETF 和反向杠桿 ETF,以及外匯市場。當然只是適應部分品種,從全品種統(tǒng)計來看,這是一個普適性比較強的策略。

策略編寫

根據(jù)上面的策略邏輯,我們可以在發(fā)明者量化交易平臺上實現(xiàn)交易策略。依次打開:fmz.com > 登錄 > 控制中心 > 策略庫 > 新建策略 > 點擊右上角下拉菜單選擇Python語言,開始編寫策略,注意看下面代碼中的注釋。

第1步:編寫策略框架

這個在之前的章節(jié)已經(jīng)學習過,一個是onTick函數(shù),另一個是main函數(shù),其中在main函數(shù)中無限循環(huán)執(zhí)行onTick函數(shù),如下:

def onTick():
    pass

def main():
    while True:
        onTick()
        Sleep(1000)

第2步:定義全局變量

首先定義策略中的上軌、下軌,因為我們的策略中上軌、下軌時是根據(jù)一定的條件來計算的,也就是說:當前的最高價大于前面K線的最高價時,才重新計算下軌;當前的最低價小于前面K線的最低價時,才重新計算上軌。所以我們必須把上軌和下軌變量定義在onTick主函數(shù)外面。

up_line = 0  # 上軌
under_line = 0  # 下軌
mp = 0  # 用于控制虛擬持倉

另外,我們還需要定義全局變量虛擬持倉mp,策略運行之初默認是空倉mp=0,當開多單后把虛擬持倉重置為mp=1,當開空單后把虛擬持倉重置為,mp=-1,當平多單或空單后把虛擬持倉重置為mp=0。這樣我們在判斷構(gòu)建邏輯獲取倉位時,只需要判斷mp的值就可以了。

第3步:計算上軌、下軌、中軌

因為在計算這些數(shù)據(jù)之前,肯定要先獲取歷史的K線基礎數(shù)據(jù),這些基礎數(shù)據(jù)的獲取方式也很簡單,首先訂閱期貨品種,然后調(diào)用發(fā)明者量化API中的GetRecords方法。接著因為在計算上軌和下軌的時候需要用到talib庫中的Highest和Lowest方法,這兩個方法都要傳入周期參數(shù),但如果K線數(shù)據(jù)不夠的時候,就不能正常計算其值,所以在這里就要判斷K線數(shù)據(jù)的長度,如果K線的長度不足以計算其值時,就直接返回跳過。

接著,我們分別獲取當前K線和上根K線的最高價和最低價,通過對比當前K線最高價與上根K線最高價來定義下軌的值,如果當前的最高價大于前面K線的最高價時,就重新計算下軌;同理如果當前的最低價小于前面K線的最低價時,就重新計算上軌。最后上軌和下軌的平均值就是中軌。

exchange.SetContractType("rb000")  # 訂閱期貨品種
bars = exchange.GetRecords()  # 獲取K線數(shù)組
if len(bars) < cycle_length + 1:  # 如果K線數(shù)組的長度太小,所以直接返回
    return
close0 = bars[len(bars) - 1].Close;  # 獲取當根K線收盤價
high0 = bars[len(bars) - 1].High;  # 獲取當根K線最高價
high2 = bars[len(bars) - 2].High;  # 獲取上根K線最高價
low0 = bars[len(bars) - 1].Low;  # 獲取當根K線最低價
low1 = bars[len(bars) - 2].Low;  # 獲取上根K線最低價
highs = TA.Highest(bars, cycle_length, 'High');  # 獲取前cycle_length根K線最高價的最高價
lows = TA.Lowest(bars, cycle_length, 'Low');  # 獲取前cycle_length根K線最低價的最低價
global up_line, under_line, mp  # 使用全局變量
if high0 > high2:  # 如果當根K線最高價大于上根K線最高價
    under_line = lows  # 把下軌重新賦值為:前cycle_length根K線最低價的最低價
if low0 < low1:  # 如果當根K線最低價小于上根K線最低價
    up_line = highs  # 把上軌重新賦值為:前cycle_length根K線最高價的最高價
middle_line = (lows + highs) / 2;  # 計算中軌的值

這里有一個地方需要注意,可能細心的朋友已經(jīng)發(fā)現(xiàn)了,我們在計算上軌和下軌的時候,用到了talib庫中的Highest和Lowest函數(shù),因為在發(fā)明者量化軟件中已經(jīng)內(nèi)置了這兩個常用的函數(shù),所以我們不需要像前幾節(jié)那樣在策略開頭導入talib庫,并且在使用內(nèi)置函數(shù)的時候,其寫法也略有不同,具體可以查看下方的代碼。

第4步:下單交易

有了上軌、下軌、中軌的值,就可以配合當前的最新價格開平倉交易了,我們可以回過頭再看下之前設計的交易邏輯:如果當前沒有持倉,并且價格大于上軌 * 1.05,買入開倉。如果當前沒有持倉,并且價格小于下軌 * 0.95,賣出開倉。如果當前持有多單,并且價格小于中軌,賣出平倉。如果當前持有空單,兵器價格大于中軌,買入平倉。

if mp == 0 and close0 > up_line:  # 如果當前空倉,并且最新價大于上軌
    exchange.SetDirection("buy")  # 設置交易方向和類型
    exchange.Buy(close0, 1)  # 開多單
    mp = 1  # 設置虛擬持倉的值,即有多單
    
if mp == 0 and close0 < under_line:  # 如果當前空倉,并且最新價小于下軌
    exchange.SetDirection("sell")  # 設置交易方向和類型
    exchange.Sell(close0 - 1, 1)  # 開空單
    mp = -1  # 設置虛擬持倉的值,即有空單
    
if mp > 0 and close0 < middle_line:  # 如果當前持有多單,并且最新價小于中軌
    exchange.SetDirection("closebuy")  # 設置交易方向和類型
    exchange.Sell(close0 - 1, 1)  # 平多單
    mp = 0  # 設置虛擬持倉的值,即空倉
    
if mp < 0 and close0 > middle_line:  # 如果當前持有空單,并且最新價大于中軌
    exchange.SetDirection("closesell")  # 設置交易方向和類型
    exchange.Buy(close0, 1)  # 平空單
    mp = 0  # 設置虛擬持倉的值,即空倉

下單交易使用if語句,如果條件為真,就先設置交易方向和類型,即:開多、開空、平多、平空。然后調(diào)用發(fā)明者量化軟件中的Buy或Sell下單函數(shù),最后下單之后重置虛擬持倉的狀態(tài)。

完整策略代碼

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


# 外部參數(shù)
cycle_length = 100


# 定義全局變量
up_line = 0  # 上軌
under_line = 0  # 下軌
mp = 0  # 用于控制虛擬持倉


def onTick():
    exchange.SetContractType("rb000")  # 訂閱期貨品種
    bars = exchange.GetRecords()  # 獲取K線數(shù)組
    if len(bars) < cycle_length + 1:  # 如果K線數(shù)組的長度太小,所以直接返回
        return
    close0 = bars[len(bars) - 1].Close;  # 獲取當根K線收盤價
    high0 = bars[len(bars) - 1].High;  # 獲取當根K線最高價
    high2 = bars[len(bars) - 2].High;  # 獲取上根K線最高價
    low0 = bars[len(bars) - 1].Low;  # 獲取當根K線最低價
    low1 = bars[len(bars) - 2].Low;  # 獲取上根K線最低價
    highs = TA.Highest(bars, cycle_length, 'High');  # 獲取前cycle_length根K線最高價的最高價
    lows = TA.Lowest(bars, cycle_length, 'Low');  # 獲取前cycle_length根K線最低價的最低價
    global up_line, under_line, mp  # 使用全局變量
    if high0 > high2:  # 如果當根K線最高價大于上根K線最高價
        under_line = lows  # 把下軌重新賦值為:前cycle_length根K線最低價的最低價
    if low0 < low1:  # 如果當根K線最低價小于上根K線最低價
        up_line = highs  # 把上軌重新賦值為:前cycle_length根K線最高價的最高價
    middle_line = (lows + highs) / 2;  # 計算中軌的值
    
    if mp == 0 and close0 > up_line:  # 如果當前空倉,并且最新價大于上軌
        exchange.SetDirection("buy")  # 設置交易方向和類型
        exchange.Buy(close0, 1)  # 開多單
        mp = 1  # 設置虛擬持倉的值,即有多單
        
    if mp == 0 and close0 < under_line:  # 如果當前空倉,并且最新價小于下軌
        exchange.SetDirection("sell")  # 設置交易方向和類型
        exchange.Sell(close0 - 1, 1)  # 開空單
        mp = -1  # 設置虛擬持倉的值,即有空單
        
    if mp > 0 and close0 < middle_line:  # 如果當前持有多單,并且最新價小于中軌
        exchange.SetDirection("closebuy")  # 設置交易方向和類型
        exchange.Sell(close0 - 1, 1)  # 平多單
        mp = 0  # 設置虛擬持倉的值,即空倉
        
    if mp < 0 and close0 > middle_line:  # 如果當前持有空單,并且最新價大于中軌
        exchange.SetDirection("closesell")  # 設置交易方向和類型
        exchange.Buy(close0, 1)  # 平空單
        mp = 0  # 設置虛擬持倉的值,即空倉
    

def main():
    while True:
        onTick()
        Sleep(1000)

感謝各位的閱讀!關于“python如何實現(xiàn)動態(tài)階梯突破策略”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI