!
導(dǎo)入失敗
?
海龜交易策略原理
核心思路就是四個(gè)字——趨勢(shì)跟蹤
。
雖然思路簡(jiǎn)單,但是實(shí)現(xiàn)起來(lái)并不簡(jiǎn)單。為了實(shí)現(xiàn)趨勢(shì)跟蹤,海龜交易策略設(shè)置了三個(gè)交易階段——入市
、加倉(cāng)
、退出
。
下圖簡(jiǎn)單地解釋了它們的含義。
!
導(dǎo)入失敗
?
入市
入市就是指買入第一筆訂單。這個(gè)階段需要解決兩個(gè)問(wèn)題——什么時(shí)候買、買多少。
也就是買入的時(shí)機(jī)和數(shù)量。
時(shí)機(jī)
既然是趨勢(shì)跟蹤類策略,肯定要在價(jià)格有上漲趨勢(shì)的時(shí)候買。
海龜交易策略使用的是另一個(gè)非常經(jīng)典的技術(shù)指標(biāo)——唐奇安通道
來(lái)判斷上漲趨勢(shì)。
什么是唐奇安通道
唐奇安通道的英文全稱是 Donchian Channel,簡(jiǎn)稱 DC。
它是上個(gè)世紀(jì)美國(guó)期貨交易員理查德·唐奇安 (Richard Donchian) 發(fā)明的技術(shù)分析指標(biāo),一般用來(lái)追蹤趨勢(shì)。
它的圖表形態(tài)和布林帶類似,由三條線組成,分別為上軌、中軌、下軌。
三條線的含義很簡(jiǎn)單,下圖是它們的計(jì)算方式:
!
導(dǎo)入失敗
?
數(shù)量
在海龜交易策略中,并非隨便設(shè)置一個(gè)買入數(shù)量就可以。
它采取了一種特殊的計(jì)算方式,能靈活調(diào)整買入數(shù)量,以達(dá)到風(fēng)險(xiǎn)控制的目的。
看一下計(jì)算公式:
!
導(dǎo)入失敗
?
公式中的 ATR(平均真實(shí)波幅)
,我們之前學(xué)習(xí)過(guò)。它用來(lái)衡量?jī)r(jià)格波動(dòng)幅度,ATR 越大,表示價(jià)格波動(dòng)越大,反之波動(dòng)越小。
在公式中,買入數(shù)量在等式左邊,ATR 在右邊的分母位置。
根據(jù)中學(xué)數(shù)學(xué)知識(shí),我們知道,二者是反比關(guān)系。也就是說(shuō)——ATR 越大,買入數(shù)量越少;ATR 越小,買入數(shù)量越多。
那么,分子位置的 賬戶總資金的 1%
是什么意思呢?
把公式變個(gè)形會(huì)更容易理解。
!
導(dǎo)入失敗
?
等式的左邊是買入數(shù)量乘以 ATR,我們思考一下它的含義。
ATR 代表單位數(shù)量的價(jià)格波幅,乘以買入數(shù)量后,就等于整個(gè)持倉(cāng)的波幅。
例如,每噸期貨的價(jià)格波幅是 1 元,如果買入 10 噸,整個(gè)持倉(cāng)的波幅就是 10 元。
因此,這個(gè)等式的實(shí)際含義是:整個(gè)持倉(cāng)的波幅 = 賬戶總資金的 1%
加倉(cāng)
加倉(cāng)是指,入市之后如果價(jià)格繼續(xù)上漲,就繼續(xù)買入訂單。
顯然,我們同樣要解決兩個(gè)問(wèn)題——加倉(cāng)的時(shí)機(jī)和數(shù)量。
時(shí)機(jī)
怎么判斷價(jià)格是否會(huì)繼續(xù)上漲呢?
入市時(shí)判斷上漲趨勢(shì)的方法是唐奇安通道,加倉(cāng)則不太一樣。
海龜交易策略是這樣判斷的——與上一次買入的價(jià)格相比,價(jià)格上漲了超過(guò) 0.5 個(gè) ATR,就執(zhí)行加倉(cāng)。
!
導(dǎo)入失敗
?
如果執(zhí)行一次加倉(cāng)后,價(jià)格再次上漲了 0.5
個(gè) ATR,可以再次加倉(cāng)。
加倉(cāng)越多,持倉(cāng)風(fēng)險(xiǎn)也隨之增大。為了控制風(fēng)險(xiǎn),策略會(huì)設(shè)置一個(gè)買入次數(shù)上限,一般默認(rèn)為 4
次(入市和加倉(cāng)合計(jì) 4 次)。
你需要對(duì)加倉(cāng)階段的兩個(gè)關(guān)鍵參數(shù)有印象。
一個(gè)是 0.5
,它是加倉(cāng)波幅系數(shù)
;另一個(gè)是 4
,它代表買入次數(shù)上限
。
數(shù)量
那么,加倉(cāng)一次,需要買入多少訂單呢?
這里的計(jì)算方式和入市階段完全相同,直接照搬公式即可。
!
導(dǎo)入失敗
?
!
導(dǎo)入失敗
?
退出
退出是指,當(dāng)價(jià)格有不利趨勢(shì)時(shí),執(zhí)行平倉(cāng)。
入市和加倉(cāng)利用的是上漲趨勢(shì)。但是,市場(chǎng)往往不遂人愿,一旦趨勢(shì)不利,我們要果斷退出。
這本質(zhì)是一種風(fēng)控。
時(shí)機(jī)
海龜交易策略使用了兩個(gè)條件來(lái)判斷不利趨勢(shì):
a. 止損:與上一次買入價(jià)格相比,價(jià)格下跌了超過(guò) 2 個(gè) ATR,平倉(cāng)退出。注意,此處的“2” ,我們將它理解為止損波幅系數(shù)。
!
導(dǎo)入失敗
?
b. 止盈:當(dāng)前交易日價(jià)格突破下軌,平倉(cāng)退出。
!
導(dǎo)入失敗
?
價(jià)格突破唐奇安通道下軌,說(shuō)明達(dá)到了過(guò)去 M 個(gè)交易日的價(jià)格最低點(diǎn),此時(shí)認(rèn)為,價(jià)格趨勢(shì)可能出現(xiàn)反轉(zhuǎn)。
止損和止盈這兩個(gè)條件只要滿足其一,就立即平倉(cāng)退出。
數(shù)量
退出就是賣出全部持倉(cāng)。
退出后,一次完整的海龜交易就結(jié)束了。如果要繼續(xù)交易,要重新從入市開(kāi)始。
這就是退出階段的全部邏輯,總結(jié)一下:
!
導(dǎo)入失敗
?
總結(jié)一下,海龜交易策略的核心理念無(wú)非以下兩條:
1)根據(jù)唐奇安通道和 ATR 判斷買賣時(shí)機(jī),漲勢(shì)就買入,跌勢(shì)就平倉(cāng);
2)根據(jù) ATR 計(jì)算買入數(shù)量,波動(dòng)大就少買,波動(dòng)小就多買,從而控制風(fēng)險(xiǎn)。
海龜交易策略建模
背景
馬奔奔有 100 萬(wàn)資金,希望用海龜交易策略做一次期貨交易。
她選擇的期貨合約是 FU2205
(燃料油),合約的詳細(xì)信息如下圖所示:
!
導(dǎo)入失敗
?
數(shù)學(xué)關(guān)系
!
導(dǎo)入失敗
?
海龜策略代碼講解實(shí)現(xiàn)
!
導(dǎo)入失敗
?
指標(biāo)模塊
指標(biāo)模塊的任務(wù)有兩個(gè)——計(jì)算關(guān)鍵指標(biāo)和設(shè)置常量。
!
導(dǎo)入失敗
?
如下圖中標(biāo)記的,在我們剛剛梳理的數(shù)學(xué)關(guān)系中,就已經(jīng)用到了全部的指標(biāo)和常量。
!
導(dǎo)入失敗
?
第一類:唐奇安通道指標(biāo)
周期不同,上下軌的計(jì)算結(jié)果可能不同。
因此,我們要做的第一件事就是確定計(jì)算周期。
dc_high_period 代表上軌的計(jì)算周期。取值設(shè)為 20,表示上軌是過(guò)去 20 個(gè)交易日的價(jià)格最高點(diǎn)。
dc_low_period 代表下軌的計(jì)算周期。取值設(shè)為 10,表示下軌是過(guò)去 10 個(gè)交易日的價(jià)格最低點(diǎn)。
上軌周期 N 和下軌周期 M 并不需要相同,可以根據(jù)具體情況靈活調(diào)整。案例中的 20 和 10 只是一種比較常用的取值組合。
確定周期后,就可以計(jì)算上下軌了。
計(jì)算上軌,將結(jié)果儲(chǔ)存在變量 dc_high_line 中。
具體計(jì)算過(guò)程比較長(zhǎng),F(xiàn)orTrader 把它封裝了起來(lái)。
我們可以調(diào)用 DonchianChannel() 類
,傳入?yún)?shù),直接獲取計(jì)算結(jié)果。
調(diào)用語(yǔ)法如下圖所示:
!
導(dǎo)入失敗
?
然后需要判斷是否突破軌道。
判斷價(jià)格是否突破上軌,并將突破信號(hào)儲(chǔ)存在變量 context.dc_high_signal 中。
判斷價(jià)格是否突破下軌,把突破信號(hào)儲(chǔ)存在變量 context.dc_low_signal 中。
這兩行需要調(diào)用 CrossOver() 類
來(lái)實(shí)現(xiàn)。
CrossOver() 類在前面的關(guān)卡學(xué)習(xí)過(guò),如果忘記了可以簡(jiǎn)單復(fù)習(xí)一下:
!
導(dǎo)入失敗
?
第二類:ATR 指標(biāo)
和唐奇安通道一樣,想計(jì)算 ATR 同樣要先確認(rèn)周期。
atr_period 代表 ATR 的計(jì)算周期,設(shè)為 20。它表示計(jì)算過(guò)去 20 個(gè)交易日的平均真實(shí)波幅,是比較常用取值。
計(jì)算 ATR 指標(biāo),儲(chǔ)存在變量 context.atr 中。
計(jì)算 ATR 指標(biāo)需要調(diào)用 AverageTrueRange() 類,語(yǔ)法參照下圖:
!
導(dǎo)入失敗
?
第三類:其他常量
!
導(dǎo)入失敗
?
標(biāo)的模塊
馬奔奔選擇的標(biāo)的是 FU2205。
標(biāo)的部分的代碼如下,簡(jiǎn)單看一下即可 ??。
def choose_stock(context):
"""標(biāo)的"""
context.symbol_list = ["FU2205.XSGE"]
擇時(shí)模塊
擇時(shí)模塊要做的事只有一件——入市。
剛剛在指標(biāo)模塊中,我們用 CrossOver() 類
計(jì)算出了上軌突破信號(hào),儲(chǔ)存在變量 context.dc_high_sighnal 中。
如果 context.dc_high_signal[0] = 1.0,就表示當(dāng)前交易日的價(jià)格突破上軌。
此外,context.buy_account 是累計(jì)買入次數(shù),等于 0 時(shí)表示此前尚未買入過(guò)訂單。
兩個(gè)條件同時(shí)滿足,執(zhí)行買入,因此用 and
連接。
買入數(shù)量 = 賬戶總資金 * 賬戶風(fēng)險(xiǎn)比例 / ATR。如果忘記了公式的含義,記得及時(shí)復(fù)習(xí)。
風(fēng)控模塊
風(fēng)控模塊需要實(shí)現(xiàn)兩個(gè)階段的功能——加倉(cāng)和退出。
!
導(dǎo)入失敗
?
第一部分:持倉(cāng)判斷
判斷當(dāng)前是否持倉(cāng)。
無(wú)論是加倉(cāng)還是退出,前提都是已經(jīng)入市。
如果當(dāng)前未持倉(cāng),即 context.position_size = 0,說(shuō)明尚未入市,則用 return 跳出風(fēng)控模塊,不再執(zhí)行后面的代碼。反之,則繼續(xù)向下運(yùn)行。
第二部分:退出階段
計(jì)算止損價(jià),命名為 stop_price。用于判斷退出(止損)時(shí)機(jī)。
止損價(jià)的計(jì)算邏輯是,在上次買入價(jià)格的基礎(chǔ)上,減去 2 個(gè) ATR。一旦價(jià)格低過(guò)這條線,就說(shuō)明符合退出(止損)時(shí)機(jī),執(zhí)行平倉(cāng)。
第一,context.dc_low_signal[0] 表示下軌突破信號(hào),它等于 -1.0 時(shí),代表價(jià)格突破唐奇安通道下軌。
第二,context.data.close[0] < stop_price 表示價(jià)格低于止損價(jià)。
兩者滿足其一,就可以執(zhí)行平倉(cāng),因此用 or
連接。
執(zhí)行平倉(cāng)后需要重置買入次數(shù)。
一旦滿足退出條件,就平掉全部持倉(cāng),一次完整的海龜交易結(jié)束。同時(shí),累計(jì)買入次數(shù)要重置為 0,以便開(kāi)始新一輪海龜交易。
第三部分:加倉(cāng)階段
計(jì)算加倉(cāng)價(jià),命名為 scale_price。用于判斷加倉(cāng)時(shí)機(jī)。
第一,context.data.close[0] > scale_price 表示價(jià)格高于加倉(cāng)價(jià)。
第二,context.buy_count < context.scale_number 表示累計(jì)加倉(cāng)次數(shù)小于加倉(cāng)次數(shù)上線,即累計(jì)買入次數(shù)未達(dá)到上限。
兩個(gè)條件同時(shí)滿足時(shí),執(zhí)行加倉(cāng),因此用 and
連接。
計(jì)算加倉(cāng)數(shù)量。
加倉(cāng)數(shù)量的計(jì)算公式和入市階段相同,同樣要記得把結(jié)果處理成 10 的整數(shù)倍。
發(fā)送加倉(cāng)指令,更新累計(jì)買入次數(shù)和買入價(jià)格。
每次加倉(cāng)買入后,累計(jì)買入次數(shù)都需要加 1,并把買入價(jià)格記錄下來(lái)。
執(zhí)行代碼
指標(biāo)模塊代碼:
def indicators(context):
"""指標(biāo)"""
# 設(shè)置唐奇安通道相關(guān)參數(shù)
# 設(shè)置唐奇安通道上軌周期
dc_high_period = 20
# 設(shè)置唐奇安通道下軌周期
dc_low_period = 10
# 獲取唐奇安通道上軌
dc_high_line = DonchianChannel(context.data, period=dc_high_period).top(-1)
# 獲取唐奇安通道下軌
dc_low_line = DonchianChannel(context.data, period=dc_low_period).bot(-1)
# 獲取收盤(pán)價(jià)與唐奇安通道上軌突破信號(hào)
context.dc_high_signal = CrossOver(context.data.close, dc_high_line)
# 獲取收盤(pán)價(jià)與唐奇安通道下軌突破信號(hào)
context.dc_low_signal = CrossOver(context.data.close, dc_low_line)
# 設(shè)置 ATR 相關(guān)參數(shù)
# 設(shè)置平均真實(shí)波幅周期
atr_period = 20
# 獲取平均真實(shí)波幅 ATR
context.atr = AverageTrueRange(context.data, period=atr_period)
# 設(shè)置其他與交易相關(guān)的常量
# 設(shè)置加倉(cāng)波幅系數(shù)
context.scale_ratio = 0.5
# 設(shè)置買入次數(shù)上限
context.scale_number = 4
# 設(shè)置止損波幅系數(shù)
context.stop_ratio = 2
# 設(shè)置賬戶風(fēng)險(xiǎn)比例
context.account_risk = 0.01
# 初始化累計(jì)買入次數(shù)
context.buy_count = 0
# 初始化上一次買入價(jià)格
context.last_buy_price = 0
標(biāo)的模塊代碼:
def choose_stock(context):
"""標(biāo)的"""
context.symbol_list = ["FU2205.XSGE"]
擇時(shí)模塊代碼:
def timing(context):
"""擇時(shí)"""
# 標(biāo)的收盤(pán)價(jià)向上突破唐奇安通道上軌,且當(dāng)前未持倉(cāng)時(shí),出現(xiàn)入市信號(hào)
if context.dc_high_signal[0] == 1.0 and context.buy_count == 0:
# 計(jì)算買入數(shù)量
size = context.broker.cash * context.account_risk / context.atr[0] // 10 * 10
# 發(fā)送買入指令
context.buy(data=context.data, size=size)
# 更新買入次數(shù)
context.buy_count = 1
# 以當(dāng)前收盤(pán)價(jià)作為買入價(jià)格
context.last_buy_price = context.data.close[0]
風(fēng)控模塊代碼:
def control_risk(context):
"""風(fēng)控"""
# 如果當(dāng)前未持倉(cāng)
if context.position.size == 0:
# 跳出該函數(shù)
return
# 計(jì)算加倉(cāng)價(jià)
scale_price = context.last_buy_price + context.scale_ratio * context.atr[0]
# 計(jì)算止損價(jià)
stop_price = context.last_buy_price - context.stop_ratio * context.atr[0]
# 如果標(biāo)的收盤(pán)價(jià)向下突破唐奇安通道下軌,或收盤(pán)價(jià)小于止損價(jià)
if context.dc_low_signal[0] == -1.0 or context.data.close[0] < stop_price:
# 發(fā)送平倉(cāng)指令
context.close(data=context.data)
# 更新買入次數(shù)
context.buy_count = 0
# 如果標(biāo)的收盤(pán)價(jià)大于加倉(cāng)價(jià),并且累計(jì)加倉(cāng)次數(shù)小于加倉(cāng)次數(shù)上限時(shí)
elif context.data.close[0] > scale_price and context.buy_count < context.scale_number:
# 計(jì)算加倉(cāng)數(shù)量
size = context.broker.cash * context.account_risk / context.atr[0] // 10 * 10
# 發(fā)送加倉(cāng)指令
context.buy(data=context.data, size=size)
# 更新累計(jì)買入次數(shù)
context.buy_count += 1
# 以當(dāng)前收盤(pán)價(jià)作為買入價(jià)格
context.last_buy_price = context.data.close[0]
初次回測(cè)
!
導(dǎo)入失敗
?
海龜交易策略參數(shù)調(diào)優(yōu)
調(diào)參邏輯
想要有目的地調(diào)參,我們需要知道有哪些參數(shù)可以調(diào),以及參數(shù)是如何影響策略運(yùn)行的。
不難發(fā)現(xiàn),海龜交易策略中可調(diào)節(jié)的參數(shù),也可以分為三類:唐奇安通道相關(guān)參數(shù)
、ATR 相關(guān)參數(shù)
、其他常量參數(shù)
。
我們逐個(gè)來(lái)看。
5.1.1 唐奇安通道相關(guān)參數(shù)
能夠影響唐奇安通道的參數(shù)有兩個(gè):
1)dc_high_period:上軌周期
2)dc_low_period:下軌周期
以上軌周期為例。周期長(zhǎng),說(shuō)明計(jì)算上軌時(shí)所涵蓋的歷史數(shù)據(jù)更久遠(yuǎn),反映的是較長(zhǎng)周期內(nèi)的價(jià)格最高點(diǎn)。而周期短,則反映的是短期內(nèi)的價(jià)格最高點(diǎn)。
一般而言,周期不宜太短也不宜太長(zhǎng)。
如果周期太長(zhǎng),會(huì)導(dǎo)致價(jià)格很難突破軌道,從而錯(cuò)過(guò)一些漲跌趨勢(shì)。
如果周期太短,會(huì)導(dǎo)致價(jià)格很容易突破,但可能是受隨機(jī)波動(dòng)的影響,趨勢(shì)的可信度會(huì)下降。
根據(jù)海龜交易策略總結(jié)出的經(jīng)驗(yàn),上軌和下軌的調(diào)參范圍如下表所示 ??。
!
導(dǎo)入失敗
?
ATR 相關(guān)參數(shù)
能夠影響 ATR 的參數(shù)也是它的計(jì)算周期——atr_period。
ATR 周期的調(diào)參思路也是類似的,既不宜過(guò)短,也不宜過(guò)長(zhǎng)。
其調(diào)參范圍如下所示 ??。?
!
導(dǎo)入失敗
?
其他常量參數(shù)
!
導(dǎo)入失敗
?
思維導(dǎo)圖
!
導(dǎo)入失敗
?
提示:
本公司發(fā)布內(nèi)容均為市場(chǎng)公開(kāi)信息,不構(gòu)成投資建議,投資者據(jù)此操作,風(fēng)險(xiǎn)自擔(dān)。市場(chǎng)有風(fēng)險(xiǎn),投資需謹(jǐn)慎!