溫馨提示×

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

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

python如何實(shí)現(xiàn)日內(nèi)高低點(diǎn)突破策略

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

這篇文章將為大家詳細(xì)講解有關(guān)python如何實(shí)現(xiàn)日內(nèi)高低點(diǎn)突破策略,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

什么是日內(nèi)交易

日內(nèi)交易的目的是以更小的損失,來(lái)獲取當(dāng)天市場(chǎng)微小的價(jià)格波動(dòng)所帶來(lái)的利潤(rùn)。它是指開(kāi)倉(cāng)和平倉(cāng)在同一天內(nèi)或同一交易時(shí)間段內(nèi)完成的交易方式,開(kāi)倉(cāng)和平倉(cāng)可以是單次,也可以是多次,只要是開(kāi)平倉(cāng)在同一個(gè)交易日前結(jié)束就行。

理論上日內(nèi)交易不承擔(dān)隔夜的跳空風(fēng)險(xiǎn),是一種較完美的低風(fēng)險(xiǎn)交易策略,但實(shí)際上并非如此,雖然日內(nèi)交易回避了跳空所帶來(lái)的風(fēng)險(xiǎn),同時(shí)也錯(cuò)失了跳空所帶來(lái)的利潤(rùn)。但如果以正確的方式交易,通過(guò)配合不同的交易規(guī)則,日內(nèi)交易往往也能產(chǎn)生豐厚的回報(bào)。

策略邏輯

我們知道判斷上漲趨勢(shì)最簡(jiǎn)單的方法是,當(dāng)前低點(diǎn)比前一個(gè)低點(diǎn)更高,當(dāng)前高點(diǎn)也比前一個(gè)高點(diǎn)更高;同理下跌趨勢(shì)最簡(jiǎn)單的方法是,當(dāng)前低點(diǎn)比前一個(gè)低點(diǎn)更低,當(dāng)前高點(diǎn)也比前一個(gè)高點(diǎn)更低。但如果僅僅以高低點(diǎn)的比較去判斷趨勢(shì)的漲跌,這未免太過(guò)簡(jiǎn)陋,因?yàn)閮r(jià)格可能在一個(gè)點(diǎn)上來(lái)回跳動(dòng)幾十次甚至上百次,從而導(dǎo)致交易過(guò)于頻繁。

所以我們需要設(shè)定一個(gè)價(jià)格區(qū)間來(lái)過(guò)濾這些日常雜波,來(lái)對(duì)簡(jiǎn)單的高低點(diǎn)突破策略進(jìn)行完善。我們可以根據(jù)歷史行情所出現(xiàn)的最高價(jià)和最低價(jià),組成一個(gè)包含上軌和下軌的通道。根據(jù)順勢(shì)交易的原則,當(dāng)價(jià)格突破上軌時(shí)多頭開(kāi)倉(cāng),當(dāng)價(jià)格突破下軌時(shí)空頭開(kāi)倉(cāng)。

  • 多頭開(kāi)倉(cāng):當(dāng)前無(wú)持倉(cāng),時(shí)間是在開(kāi)盤(pán)與收盤(pán)前10分鐘之間,并且價(jià)格大于上軌

  • 空頭開(kāi)倉(cāng):當(dāng)前無(wú)持倉(cāng),時(shí)間是在開(kāi)盤(pán)與收盤(pán)前10分鐘之間,并且價(jià)格小于下軌

  • 多頭平倉(cāng):當(dāng)前持多單,價(jià)格小于下軌,或者時(shí)間大于14:50

  • 空頭平倉(cāng):當(dāng)前持空單,價(jià)格大于上軌,或者時(shí)間大于14:50

有人統(tǒng)計(jì)過(guò),大部分的窄幅止損都是無(wú)效的,小空間的止損會(huì)頻繁打臉,所以我們要做的就是設(shè)計(jì)一個(gè)寬幅止損:如果多頭開(kāi)倉(cāng)后,價(jià)格不升反跌,我們所要做的不是立即止損,而是等待觀望,直到價(jià)格跌破下軌才止損出局;空頭開(kāi)倉(cāng)后也是如此,當(dāng)價(jià)格不跌反升,繼續(xù)等待價(jià)格是否會(huì)自我修正,直到跌破上軌才止損出局。

策略編寫(xiě)

第1步:編寫(xiě)策略框架
編寫(xiě)策略就像蓋房子一樣,先把地基和框架搭建好,再往里面填充東西。我們這里用了兩個(gè)函數(shù),一個(gè)是main主函數(shù),另一個(gè)是onTick函數(shù),程序會(huì)先從main函數(shù)執(zhí)行代碼,在main函數(shù)中,我們用了一個(gè)無(wú)限循環(huán)模式,重復(fù)執(zhí)行onTick函數(shù)。

# 策略主函數(shù)
def onTick():
    pass


# 程序入口
def main():
    while True:  # 進(jìn)入無(wú)限循環(huán)模式
        onTick()  # 執(zhí)行策略主函數(shù)
        Sleep(1000)  # 休眠1秒

第2步:導(dǎo)入time庫(kù)

# 導(dǎo)入庫(kù)
import time

因?yàn)槿諆?nèi)策略在編寫(xiě)的時(shí)候,要判斷當(dāng)前的時(shí)間來(lái)控制開(kāi)平倉(cāng)邏輯,這個(gè)策略在設(shè)計(jì)的時(shí)候是:只能在9點(diǎn)30分之14點(diǎn)50分之間開(kāi)倉(cāng),14點(diǎn)50分之后全部平倉(cāng),其余的時(shí)間都過(guò)濾掉了。所以就需要引入time時(shí)間庫(kù)。

第3步:設(shè)置全局變量

mp = 0  # 用于控制虛擬持倉(cāng)
on_line = 0  # 上軌
under_line = 0  # 下軌

在全局變量中,mp主要用于控制虛擬持倉(cāng),判斷持倉(cāng)一般分為兩種,一種是真實(shí)的賬戶持倉(cāng),另一種就是虛擬持倉(cāng),還有一種是真實(shí)持倉(cāng)和虛擬持倉(cāng)聯(lián)合判斷。實(shí)盤(pán)時(shí)我們只使用真實(shí)持倉(cāng)就足夠了,但這里為了簡(jiǎn)化策略,作為演示使用虛擬持倉(cāng)。on_line和under_line分別記錄上軌和下軌。

第4步:處理時(shí)間

# 處理時(shí)間函數(shù)
def can_time(hour, minute):
    hour = str(hour)
    minute = str(minute)
    if len(minute) == 1:
        minute = "0" + minute
    return int(hour + minute)

exchange.SetContractType("MA888")  # 訂閱期貨品種
bar_arr = exchange.GetRecords()  # 獲取K線數(shù)組 
time_new = bar_arr[len(bar_arr) - 1]['Time']  # 獲取當(dāng)根K線的時(shí)間戳
time_local_new = time.localtime(time_new / 1000)  # 處理時(shí)間戳
hour_new = int(time.strftime("%H", time_local_new))  # 格式化時(shí)間戳,并獲取小時(shí)
minute_new = int(time.strftime("%M", time_local_new))  # 格式化時(shí)間戳,并獲取分鐘
day_new = int(time.strftime("%d", time_local_new))  # 格式化時(shí)間戳,并獲取日期
time_previous = bar_arr[len(bar_arr) - 2]['Time']  # 獲取上根K線的時(shí)間戳
time_local_previous = time.localtime(time_previous / 1000)  # 處理時(shí)間戳
day_previous = int(time.strftime("%d", time_local_previous))  # 格式化時(shí)間戳,并獲取日期

處理時(shí)間一共用于兩個(gè)地方:一個(gè)是判斷當(dāng)前時(shí)間是否在我們規(guī)定的交易時(shí)間內(nèi),如果是在這個(gè)時(shí)間之內(nèi)并且達(dá)到開(kāi)倉(cāng)條件就開(kāi)倉(cāng),如果不是在這個(gè)時(shí)間之內(nèi)并且當(dāng)前有持倉(cāng)就全部平倉(cāng);另一個(gè)是判斷當(dāng)前K線是不是最新交易日的K線,如果當(dāng)前K線是最新交易日的K線,就重置on_line和under_line的值。

第4步:計(jì)算高低點(diǎn)上下軌

global mp, on_line, under_line  # 引入全局變量
high = bar_arr[len(bar_arr) - 2]['High']  # 獲取上根K線的最高價(jià)
low = bar_arr[len(bar_arr) - 2]['Low']  # 獲取上根K線的最低價(jià)
if day_new != day_previous or len(bar_arr) == 1:  # 如果當(dāng)前是第一個(gè)K線,或者是最新一根K線
    on_line = high * up # 重置上軌
    under_line = low * down  # 重置下軌
if can_time(hour_new, minute_new) < 930:  # 如果不是在規(guī)定交易的時(shí)間內(nèi)
    if high > on_line:  # 如果上根K線最高價(jià)大于上軌
        on_line = high * up  # 重置上軌
    elif low < under_line:  # 如果上根K線最低價(jià)小于下軌
        under_line = low * down  # 重置上軌

計(jì)算高低點(diǎn)上下軌的邏輯其實(shí)非常簡(jiǎn)單:如果當(dāng)前是第一根K線,那么on_line和under_line的值分別是最高價(jià)和最低價(jià),如果當(dāng)前K線是最新交易日的K線,就重置on_line和under_line的值為最高價(jià)和最低價(jià);一旦在規(guī)定的交易時(shí)間內(nèi),on_line和under_line的值就固定不變了,除非在這個(gè)時(shí)間之外并且如果上根K線最高價(jià)大于on_line就重置為最新的最高價(jià);如果上根K線最低價(jià)小于under_line就重置為最新的最低價(jià)。

第5步:下單交易

close_new = bar_arr[len(bar_arr) - 1]['Close']  # 獲取最新價(jià)格(賣(mài)價(jià)),用于開(kāi)平倉(cāng)
if mp == 0 and 930 < can_time(hour_new, minute_new) < 1450:  # 如果當(dāng)前無(wú)持倉(cāng),并且在規(guī)定的交易時(shí)間內(nèi)
    if close_new > on_line:  # 如果價(jià)格大于上軌
        exchange.SetDirection("buy")  # 設(shè)置交易方向和類(lèi)型
        exchange.Buy(close_new, 1)  # 開(kāi)多單
        mp = 1  # 設(shè)置虛擬持倉(cāng)的值,即有多單
    elif close_new < under_line:  # 如果價(jià)格小于下軌
        exchange.SetDirection("sell")  # 設(shè)置交易方向和類(lèi)型
        exchange.Sell(close_new - 1, 1)  # 開(kāi)空單
        mp = -1  # 設(shè)置虛擬持倉(cāng)的值,即有空單

# 如果持多單,并且價(jià)格小于下軌或者非規(guī)定的交易時(shí)間
if mp > 0 and (close_new < under_line or can_time(hour_new, minute_new) > 1450):
    exchange.SetDirection("closebuy")  # 設(shè)置交易方向和類(lèi)型
    exchange.Sell(close_new - 1, 1)  # 平多單
    mp = 0  # 設(shè)置虛擬持倉(cāng)的值,即空倉(cāng)

# 如果持空單,并且價(jià)格大于上軌或者非規(guī)定的交易時(shí)間
if mp < 0 and (high > on_line or can_time(hour_new, minute_new) > 1450):
    exchange.SetDirection("closesell")  # 設(shè)置交易方向和類(lèi)型
    exchange.Buy(close_new, 1)  # 平空單
    mp = 0  # 設(shè)置虛擬持倉(cāng)的值,即空倉(cāng)

在下單交易之前,我們要先獲取當(dāng)前最新價(jià)格,因?yàn)樵谙聠螘r(shí)需要在函數(shù)中傳入下單價(jià)格。然后使用if語(yǔ)句,根據(jù)之前設(shè)計(jì)的交易邏輯,先是判斷當(dāng)前的持倉(cāng)狀態(tài),然后再判斷當(dāng)前時(shí)間狀態(tài),以及最新價(jià)格與上下軌的相互位置關(guān)系,最后下單交易并重置虛擬持倉(cāng)狀態(tài)。需要注意的是在期貨交易下單之前,先指定交易的方向類(lèi)型,即:開(kāi)多、開(kāi)空、平多、平空。調(diào)用exchange.SetDirection()函數(shù),分別傳入:“buy”、“sell”、“closebuy”、“closesell”。

完整策略

# 回測(cè)配置
'''backtest
start: 2015-02-22 00:00:00
end: 2019-10-17 00:00:00
period: 5m
exchanges: [{"eid":"Futures_CTP","currency":"FUTURES"}]
'''

# 導(dǎo)入庫(kù)
import time


# 定義全局變量
mp = 0  # 用于控制虛擬持倉(cāng)
on_line = 0  # 上軌
under_line = 0  # 下軌


def onTick():
    # 處理時(shí)間函數(shù)
    def can_time(hour, minute):
        hour = str(hour)
        minute = str(minute)
        if len(minute) == 1:
            minute = "0" + minute
        return int(hour + minute)
    
    exchange.SetContractType("MA888")  # 訂閱期貨品種
    bar_arr = exchange.GetRecords()  # 獲取K線數(shù)組 
    time_new = bar_arr[len(bar_arr) - 1]['Time']  # 獲取當(dāng)根K線的時(shí)間戳
    time_local_new = time.localtime(time_new / 1000)  # 處理時(shí)間戳
    hour_new = int(time.strftime("%H", time_local_new))  # 格式化時(shí)間戳,并獲取小時(shí)
    minute_new = int(time.strftime("%M", time_local_new))  # 格式化時(shí)間戳,并獲取分鐘
    day_new = int(time.strftime("%d", time_local_new))  # 格式化時(shí)間戳,并獲取日期
    time_previous = bar_arr[len(bar_arr) - 2]['Time']  # 獲取上根K線的時(shí)間戳
    time_local_previous = time.localtime(time_previous / 1000)  # 處理時(shí)間戳
    day_previous = int(time.strftime("%d", time_local_previous))  # 格式化時(shí)間戳,并獲取日期
    
    global mp, on_line, under_line  # 引入全局變量
    high = bar_arr[len(bar_arr) - 2]['High']  # 獲取上根K線的最高價(jià)
    low = bar_arr[len(bar_arr) - 2]['Low']  # 獲取上根K線的最低價(jià)
    if day_new != day_previous or len(bar_arr) == 1:  # 如果當(dāng)前是第一個(gè)K線,或者是最新一根K線
        on_line = high * up # 重置上軌
        under_line = low * down  # 重置下軌
    if can_time(hour_new, minute_new) < 930:  # 如果不是在規(guī)定交易的時(shí)間內(nèi)
        if high > on_line:  # 如果上根K線最高價(jià)大于上軌
            on_line = high * up  # 重置上軌
        elif low < under_line:  # 如果上根K線最低價(jià)小于下軌
            under_line = low * down  # 重置上軌
    
    close_new = bar_arr[len(bar_arr) - 1]['Close']  # 獲取最新價(jià)格(賣(mài)價(jià)),用于開(kāi)平倉(cāng)
    if mp == 0 and 930 < can_time(hour_new, minute_new) < 1450:  # 如果當(dāng)前無(wú)持倉(cāng),并且在規(guī)定的交易時(shí)間內(nèi)
        if close_new > on_line:  # 如果價(jià)格大于上軌
            exchange.SetDirection("buy")  # 設(shè)置交易方向和類(lèi)型
            exchange.Buy(close_new, 1)  # 開(kāi)多單
            mp = 1  # 設(shè)置虛擬持倉(cāng)的值,即有多單
        elif close_new < under_line:  # 如果價(jià)格小于下軌
            exchange.SetDirection("sell")  # 設(shè)置交易方向和類(lèi)型
            exchange.Sell(close_new - 1, 1)  # 開(kāi)空單
            mp = -1  # 設(shè)置虛擬持倉(cāng)的值,即有空單
    
    # 如果持多單,并且價(jià)格小于下軌或者非規(guī)定的交易時(shí)間
    if mp > 0 and (close_new < under_line or can_time(hour_new, minute_new) > 1450):
        exchange.SetDirection("closebuy")  # 設(shè)置交易方向和類(lèi)型
        exchange.Sell(close_new - 1, 1)  # 平多單
        mp = 0  # 設(shè)置虛擬持倉(cāng)的值,即空倉(cāng)
    
    # 如果持空單,并且價(jià)格大于上軌或者非規(guī)定的交易時(shí)間
    if mp < 0 and (high > on_line or can_time(hour_new, minute_new) > 1450):
        exchange.SetDirection("closesell")  # 設(shè)置交易方向和類(lèi)型
        exchange.Buy(close_new, 1)  # 平空單
        mp = 0  # 設(shè)置虛擬持倉(cāng)的值,即空倉(cāng)

        
# 程序入口      
def main():
    while True:
        onTick()
        Sleep(1000)  #休眠1秒

關(guān)于“python如何實(shí)現(xiàn)日內(nèi)高低點(diǎn)突破策略”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

向AI問(wèn)一下細(xì)節(jié)

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

AI